From 82a6b6dc02cef5029f10cbd1585ee42f953222cf Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Thu, 26 Oct 2023 11:11:57 -0700 Subject: [PATCH] Better error if plugin file in baseline not found Fixes: #718 --- detect_secrets/core/plugins/initialize.py | 12 +++++++++++- detect_secrets/core/scan.py | 8 ++++++-- detect_secrets/util/importlib.py | 4 +++- tests/core/baseline_test.py | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/detect_secrets/core/plugins/initialize.py b/detect_secrets/core/plugins/initialize.py index 6d8eeaeb9..b74eab3c3 100644 --- a/detect_secrets/core/plugins/initialize.py +++ b/detect_secrets/core/plugins/initialize.py @@ -31,7 +31,17 @@ def from_plugin_classname(classname: str) -> Plugin: """ :raises: TypeError """ - for plugin_type in get_mapping_from_secret_type_to_class().values(): + try: + plugin_types = get_mapping_from_secret_type_to_class().values() + except FileNotFoundError as e: + log.error(f'Error: Failed to load `{classname}` plugin: {e}') + log.error( + 'This error can occur when using a baseline that references a ' + 'custom plugin with a path that does not exist.', + ) + raise + + for plugin_type in plugin_types: if plugin_type.__name__ == classname: break else: diff --git a/detect_secrets/core/scan.py b/detect_secrets/core/scan.py index f84d53c3c..6afa762af 100644 --- a/detect_secrets/core/scan.py +++ b/detect_secrets/core/scan.py @@ -138,8 +138,12 @@ def scan_line(line: str) -> Generator[PotentialSecret, None, None]: def scan_file(filename: str) -> Generator[PotentialSecret, None, None]: - if not get_plugins(): # pragma: no cover - log.error('No plugins to scan with!') + try: + if not get_plugins(): # pragma: no cover + log.error('No plugins to scan with!') + return + except FileNotFoundError: + log.error('Unable to load plugins!') return if _is_filtered_out(required_filter_parameters=['filename'], filename=filename): diff --git a/detect_secrets/util/importlib.py b/detect_secrets/util/importlib.py index f5e90005c..dfa9307a6 100644 --- a/detect_secrets/util/importlib.py +++ b/detect_secrets/util/importlib.py @@ -1,3 +1,4 @@ +import errno import importlib.util import os import pkgutil @@ -85,7 +86,8 @@ def import_file_as_module(filename: str, name: Optional[str] = None) -> ModuleTy for you. """ if not os.path.exists(filename): - raise FileNotFoundError + # Source: https://stackoverflow.com/a/36077407 + raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), filename) if not name: # NOTE: After several trial and error attempts, I could not discern the importance diff --git a/tests/core/baseline_test.py b/tests/core/baseline_test.py index c8e24a8f3..f25d56e28 100644 --- a/tests/core/baseline_test.py +++ b/tests/core/baseline_test.py @@ -102,6 +102,25 @@ def test_load_and_output(): break +def test_plugin_not_found_in_baseline(): + # Test fix for the issue in #718 + data = { + 'version': '1.4.0', + 'plugins_used': [{ + 'name': 'FakeCustomPlugin', + 'path': 'file://./path/to/plugin/that/does/not/exist/plugin.py', + }], + 'results': {}, + } + secrets = baseline.load(data) + with pytest.raises(FileNotFoundError) as exc_info: + baseline.format_for_output(secrets) + + # Check that filename of file that was not found is in the error message + # (#718) + exc_info.match(r'\./path/to/plugin/that/does/not/exist/plugin\.py') + + def test_upgrade_does_nothing_if_newer_version(): current_baseline = {'version': '3.0.0'} assert baseline.upgrade(current_baseline) == current_baseline