From 4009c626d4cb20c55580a156a0a7f422f61c2bfe Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Mon, 29 Jul 2019 12:05:51 -0400 Subject: [PATCH] ledger_entry: Improve error reporting for amount expressions. This is going to become more important as amount expressions become more capable. --- import2ledger/hooks/ledger_entry.py | 16 +++++++++++----- tests/data/templates.ini | 10 ++++++++++ tests/test_hook_ledger_entry.py | 9 +++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/import2ledger/hooks/ledger_entry.py b/import2ledger/hooks/ledger_entry.py index d5a6d97..17ff7f2 100644 --- a/import2ledger/hooks/ledger_entry.py +++ b/import2ledger/hooks/ledger_entry.py @@ -168,11 +168,17 @@ class AccountSplitter: def _build_amounts(self, template_vars): amount_vars = {k: v for k, v in template_vars.items() if isinstance(v, decimal.Decimal)} amount_vars['Decimal'] = decimal.Decimal - amounts = [ - (account, self._currency_decimal(eval(amount_expr, amount_vars), - template_vars['currency'])) - for account, amount_expr in self.splits - ] + try: + amounts = [ + (account, self._currency_decimal(eval(amount_expr, amount_vars), + template_vars['currency'])) + for account, amount_expr in self.splits + ] + except (ArithmeticError, NameError, TypeError, ValueError) as error: + raise errors.UserInputConfigurationError( + "{}: {}".format(type(error).__name__, error), + "template {!r}".format(self.template_name) + ) from error self._balance_amounts(amounts, template_vars['amount']) self._balance_amounts(amounts, -template_vars['amount']) return amounts diff --git a/tests/data/templates.ini b/tests/data/templates.ini index cf70544..5b8ce60 100644 --- a/tests/data/templates.ini +++ b/tests/data/templates.ini @@ -53,6 +53,16 @@ template = Expenses:Banking Fees (6 if {amount} > 50 else 3) Income:Sales -{amount} +[NondecimalWord] +template = + Income:Sales -5 + Assets:Cash foo + +[NondecimalVariable] +template = + Income:Sales -5 + Assets:Cash {payee} + [Empty] template = diff --git a/tests/test_hook_ledger_entry.py b/tests/test_hook_ledger_entry.py index fd23392..ffa7235 100644 --- a/tests/test_hook_ledger_entry.py +++ b/tests/test_hook_ledger_entry.py @@ -259,3 +259,12 @@ def test_hook_handles_template_undefined(): entry_data = template_vars('DD', 1) assert not run_hook(entry_data, 'Nonexistent') +def test_string_value_is_user_error(): + entry_data = template_vars('EE', 1) + with pytest.raises(errors.UserInputConfigurationError): + run_hook(entry_data, 'NondecimalWord') + +def test_string_variable_is_user_error(): + entry_data = template_vars('FF', 1) + with pytest.raises(errors.UserInputConfigurationError): + run_hook(entry_data, 'NondecimalVariable')