cliutil: ExceptHook catches RewriteRuleError.

Now that we have richer exceptions, this is the easiest way to refactor out
rewrite rule error handling from the various main functions where it
currenly lives.
This commit is contained in:
Brett Smith 2021-02-19 18:03:12 -05:00
parent f508df06c1
commit 0a34ed6798
2 changed files with 28 additions and 2 deletions

View file

@ -28,8 +28,10 @@ import types
from pathlib import Path from pathlib import Path
import rt.exceptions as rt_error import rt.exceptions as rt_error
import yaml
from . import data from . import data
from . import errors
from . import filters from . import filters
from . import rtutil from . import rtutil
@ -148,6 +150,11 @@ class ExceptHook:
elif isinstance(exc_value, rt_error.RtError): elif isinstance(exc_value, rt_error.RtError):
exitcode = os.EX_UNAVAILABLE exitcode = os.EX_UNAVAILABLE
error_type = f"RT {error_type}" error_type = f"RT {error_type}"
elif isinstance(exc_value, errors.RewriteRuleError):
exitcode = ExitCode.RewriteRulesError
msg = str(exc_value)
if exc_value.source is not None:
msg += f"\n\n source: {yaml.safe_dump(exc_value.source)}"
elif isinstance(exc_value, OSError): elif isinstance(exc_value, OSError):
if exc_value.filename is None: if exc_value.filename is None:
exitcode = os.EX_OSERR exitcode = os.EX_OSERR

View file

@ -1,5 +1,5 @@
"""Test CLI utilities""" """Test CLI utilities"""
# Copyright © 2020 Brett Smith # Copyright © 2020, 2021 Brett Smith
# License: AGPLv3-or-later WITH Beancount-Plugin-Additional-Permission-1.0 # License: AGPLv3-or-later WITH Beancount-Plugin-Additional-Permission-1.0
# #
# Full copyright and licensing details can be found at toplevel file # Full copyright and licensing details can be found at toplevel file
@ -23,7 +23,7 @@ from pathlib import Path
from . import testutil from . import testutil
from conservancy_beancount import cliutil from conservancy_beancount import cliutil, errors
FILE_NAMES = ['-foobar', '-foo.bin'] FILE_NAMES = ['-foobar', '-foo.bin']
STREAM_PATHS = [None, Path('-')] STREAM_PATHS = [None, Path('-')]
@ -163,6 +163,25 @@ def test_excepthook_oserror(errnum, caplog):
assert log.levelname == 'CRITICAL' assert log.levelname == 'CRITICAL'
assert log.message == f"I/O error: {error.filename}: {error.strerror}" assert log.message == f"I/O error: {error.filename}: {error.strerror}"
@pytest.mark.parametrize('errcls', [
errors.RewriteRuleActionError,
errors.RewriteRuleConditionError,
errors.RewriteRuleLoadError,
errors.RewriteRuleValidationError,
])
def test_excepthook_rewrite_rule_error(errcls, caplog):
name = errcls.__name__
error = errcls("bad rewrite rule", f"{name}.yml", 170, [name])
with pytest.raises(SystemExit) as exc_check:
cliutil.ExceptHook()(type(error), error, None)
assert exc_check.value.args[0] == cliutil.ExitCode.RewriteRulesError
assert caplog.records
for log in caplog.records:
assert log.levelname == 'CRITICAL'
lines = log.message.splitlines()
assert lines[0].startswith(f"{name}: bad rewrite rule in {name}.yml rule #170")
assert re.match(rf' source:\W+{name}\b', lines[-1])
@pytest.mark.parametrize('exc_type', [ @pytest.mark.parametrize('exc_type', [
AttributeError, AttributeError,
RuntimeError, RuntimeError,