diff options
| author | Ian Stapleton Cordasco <graffatcolmingov@gmail.com> | 2017-12-31 18:45:27 -0600 |
|---|---|---|
| committer | Ian Stapleton Cordasco <graffatcolmingov@gmail.com> | 2017-12-31 18:46:59 -0600 |
| commit | 30431155513c177a52c0f8ce0e6ed6d6274c6144 (patch) | |
| tree | af33a02478066baca4c7f494a44707a500d5ae15 /src | |
| parent | 3530870679ddb93ade9326d9e5d932596b66e8b9 (diff) | |
| download | flake8-30431155513c177a52c0f8ce0e6ed6d6274c6144.tar.gz | |
Implement better UX around broken plugins
This handles most any exception arising from a plugin and provides the
user with a better experience and view of the problem. It also provides
a way to retrieve the information about what exactly failed for
providing bug reports to plugin authors.
Diffstat (limited to 'src')
| -rw-r--r-- | src/flake8/checker.py | 10 | ||||
| -rw-r--r-- | src/flake8/exceptions.py | 19 | ||||
| -rw-r--r-- | src/flake8/main/application.py | 7 |
3 files changed, 34 insertions, 2 deletions
diff --git a/src/flake8/checker.py b/src/flake8/checker.py index 6e53cb5..7a18ce5 100644 --- a/src/flake8/checker.py +++ b/src/flake8/checker.py @@ -432,7 +432,15 @@ class FileChecker(object): plugin=plugin, exception=ae, ) - return plugin['plugin'](**arguments) + try: + return plugin['plugin'](**arguments) + except Exception as all_exc: + LOG.critical('Plugin %s raised an unexpected exception', + plugin['name']) + raise exceptions.PluginExecutionFailed( + plugin=plugin, + excetion=all_exc, + ) @staticmethod def _extract_syntax_information(exception): diff --git a/src/flake8/exceptions.py b/src/flake8/exceptions.py index 13e8996..c7217f5 100644 --- a/src/flake8/exceptions.py +++ b/src/flake8/exceptions.py @@ -76,6 +76,25 @@ class PluginRequestedUnknownParameters(Flake8Exception): 'exc': self.original_exception} +class PluginExecutionFailed(Flake8Exception): + """The plugin failed during execution.""" + + FORMAT = '"%(name)s" failed during execution due to "%(exc)s"' + + def __init__(self, *args, **kwargs): + """Utilize keyword arguments for message generation.""" + self.original_exception = kwargs.pop('exception') + self.plugin = kwargs.pop('plugin') + super(PluginExecutionFailed, self).__init__( + str(self), *args, **kwargs + ) + + def __str__(self): + """Format our exception message.""" + return self.FORMAT % {'name': self.plugin['plugin_name'], + 'exc': self.original_exception} + + class HookInstallationError(Flake8Exception): """Parent exception for all hooks errors.""" diff --git a/src/flake8/main/application.py b/src/flake8/main/application.py index 233b9af..aed6175 100644 --- a/src/flake8/main/application.py +++ b/src/flake8/main/application.py @@ -309,7 +309,12 @@ class Application(object): if self.running_against_diff: files = sorted(self.parsed_diff) self.file_checker_manager.start(files) - self.file_checker_manager.run() + try: + self.file_checker_manager.run() + except exceptions.PluginExecutionFailed as plugin_failed: + print(str(plugin_failed)) + print('Run flake8 with greater verbosity to see more details') + self.catastrophic_failure = True LOG.info('Finished running') self.file_checker_manager.stop() self.end_time = time.time() |
