diff --git a/informed_decision/web.py b/informed_decision/web.py index 6730947..b3ea736 100644 --- a/informed_decision/web.py +++ b/informed_decision/web.py @@ -188,7 +188,7 @@ class App: if method == "GET" and path == "/": if session: content = (f"

Signed in as {html.escape(session.subject)}.

" - + (overview_section(self.review.overview(session)) if self.review is not None else '') + + (self._overview(session) if self.review is not None else '') + ('

Open a decision review

Enter the memo identifier supplied with your review request.

' '
' '
' if self.review is not None else @@ -201,6 +201,19 @@ class App: return 200, document("Informed Decision", content, session.subject if session else None), "text/html", [] return 404, "Not found.", "text/plain", [] + def _overview(self, session): + # The overview is orientation only. Its failure must never take the + # memo form, sign-out or an unresolved-entry recovery path with it. + try: + return overview_section(self.review.overview(session)) + except ReviewError as exc: + if exc.code == "session_expired": + raise + except (PolicyError, ApprovalEngineError, StoreError, sqlite3.Error, ValueError, KeyError, TypeError): + pass + return ('

Your decisions

Your decisions could not be ' + 'listed right now. You can still open a review by its memo identifier.
') + def _form(self, environ, session): if environ.get("HTTP_ORIGIN") != ORIGIN: raise ReviewError(403, "invalid_form") diff --git a/tests/test_review_controller.py b/tests/test_review_controller.py index eda21b9..f737cd7 100644 --- a/tests/test_review_controller.py +++ b/tests/test_review_controller.py @@ -407,3 +407,11 @@ def test_home_without_session_shows_sign_in_only(review): r=call(app,'/') assert 'Sign in with KeyCape' in r['body'] and 'Your decisions' not in r['body'] assert controller.store.policy_observations()==[] + + +def test_home_keeps_the_memo_form_when_the_overview_fails(review,monkeypatch): + controller,session,app,*_=review + def broken(subject):raise sqlite3.OperationalError('disk') + monkeypatch.setattr(controller.store,'memos_for',broken) + r=home(review) + assert r['status']==200 and 'could not be listed right now' in r['body'] and 'Open a decision review' in r['body']