Handle AttributeErrors during parameter aggregation

Plugins do not have their parameters checked in advance, so when we
try to aggregate parameters for a plugin, there's a chance it may
request an attribute of the FileProcessor that simply does not exist.

We catch this and re-raise it but we should also capture it in the
checker manager and handle it appropriately there as well.
This commit is contained in:
Ian Cordasco 2016-07-27 07:17:29 -05:00
parent 846bfafe6c
commit 47e3e65cc1
No known key found for this signature in database
GPG key ID: 656D3395E4A9791A
2 changed files with 41 additions and 5 deletions

View file

@ -40,10 +40,17 @@ SERIAL_RETRY_ERRNOS = set([
def _run_checks_from_queue(process_queue, results_queue, statistics_queue):
LOG.info('Running checks in parallel')
for checker in iter(process_queue.get, 'DONE'):
LOG.info('Checking "%s"', checker.filename)
checker.run_checks(results_queue, statistics_queue)
results_queue.put('DONE')
try:
for checker in iter(process_queue.get, 'DONE'):
LOG.info('Checking "%s"', checker.filename)
checker.run_checks(results_queue, statistics_queue)
except exceptions.PluginRequestedUnknownParameters as exc:
print(str(exc))
except Exception as exc:
LOG.error('Unhandled exception occurred')
raise
finally:
results_queue.put('DONE')
class Manager(object):
@ -356,6 +363,8 @@ class Manager(object):
except KeyboardInterrupt:
LOG.warning('Flake8 was interrupted by the user')
raise exceptions.EarlyQuit('Early quit while running checks')
finally:
self._force_cleanup()
def start(self, paths=None):
"""Start checking files.
@ -447,7 +456,14 @@ class FileChecker(object):
def run_check(self, plugin, **arguments):
"""Run the check in a single plugin."""
LOG.debug('Running %r with %r', plugin, arguments)
self.processor.keyword_arguments_for(plugin.parameters, arguments)
try:
self.processor.keyword_arguments_for(plugin.parameters, arguments)
except AttributeError as ae:
LOG.error('Plugin requested unknown parameters.')
raise exceptions.PluginRequestedUnknownParameters(
plugin=plugin,
exception=ae,
)
return plugin.execute(**arguments)
def run_ast_checks(self):

View file

@ -49,6 +49,26 @@ class InvalidSyntax(Flake8Exception):
super(InvalidSyntax, self).__init__(*args, **kwargs)
class PluginRequestedUnknownParameters(Flake8Exception):
"""The plugin requested unknown parameters."""
FORMAT = '"%(name)s" requested unknown parameters causing %(exc)s'
def __init__(self, *args, **kwargs):
"""Pop certain keyword arguments for initialization."""
self.original_exception = kwargs.pop('exception')
self.plugin = kwargs.pop('plugin')
super(PluginRequestedUnknownParameters, self).__init__(
*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."""