Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle exceptions when retrieving account balances #68

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/gnucash_web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def create_app(test_config=None):
app.jinja_env.filters['full_account_names'] = jinja_utils.full_account_names
app.jinja_env.filters['contrasplits'] = jinja_utils.contra_splits
app.jinja_env.filters['nth'] = jinja_utils.nth
app.jinja_env.filters['safe_get_balance'] = jinja_utils.safe_get_balance
app.jinja_env.globals['is_authenticated'] = auth.is_authenticated

with (Path(__file__).parent / 'version.txt').open() as version:
Expand Down
4 changes: 2 additions & 2 deletions src/gnucash_web/templates/account.j2
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<div class="list-group-item">
<b>Total</b>
<span class="float-end">
{{ account.get_balance() | money(account.commodity) }}
{{ account | safe_get_balance | money(account.commodity) }}
</span>
</div>
</div>
Expand All @@ -54,7 +54,7 @@
</a>

<span class="float-end">
{{ account.get_balance() | money(account.commodity) }}
{{ account | safe_get_balance | money(account.commodity) }}
</span>
</div>

Expand Down
14 changes: 14 additions & 0 deletions src/gnucash_web/utils/jinja.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Utilities for templates."""
import logging
import re
from urllib.parse import quote_plus
from itertools import islice, accumulate
Expand All @@ -8,6 +9,7 @@
from babel import numbers
from markupsafe import Markup, escape
from jinja2 import Environment, BaseLoader, pass_eval_context
from piecash import GnucashException


def safe_display_string(string):
Expand Down Expand Up @@ -59,6 +61,9 @@ def money(eval_ctx, amount, commodity):
:returns: HTML snippet

"""
if amount is None:
return Markup('<span class="text-danger">Error</span>')
Comment on lines +64 to +65
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which cases can the amount be None? Is it an invalid database then? Do you know how one arrives at such a state?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a GnucashException was raised, the safe_get_balance filter returns None as an amount.


if numbers.get_currency_symbol(commodity.mnemonic) != commodity.mnemonic:
value = numbers.format_currency(amount, commodity.mnemonic)
else:
Expand Down Expand Up @@ -132,3 +137,12 @@ def contra_splits(split):
def nth(iterable, n, default=None):
"Returns the nth item or a default value"
return next(islice(iterable, n, None), default)


def safe_get_balance(account):
"""Get balance of account, but catch piecash exceptions."""
try:
return account.get_balance()
except GnucashException as e:
logging.warning(f"Failed to retrieve balance for account {account}: {e}")
return None
Comment on lines +146 to +148
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar question: What are the circumstances that lead to an exception in this case. Invalid database? Can this happen when using simply the GnuCash Desktop-App and gnucash_web?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piecash raises this exception when there is no direct exchange rate between two currencies. This can occur in legitimate scenarios and is not necessarily due to an invalid database.

In my case, I had a EUR account with a USD account as its parent. Neither of these currencies is the default currency in my GnuCash book; the default is CAD. As a result, I only had conversion rates for USD-CAD and EUR-CAD, but not for USD-EUR. When attempting to read this database in gnucash-web, the absence of a direct exchange rate caused an unhandled exception, resulting in an HTTP 500 error.

This database was created entirely using the GnuCash desktop app and has not been modified by any other tool.