Skip to content

Stop rendering raw exceptions when court report generation fails - #7097

Merged
compwron merged 2 commits into
mainfrom
fix-court-report-error-handling
Aug 7, 2026
Merged

Stop rendering raw exceptions when court report generation fails#7097
compwron merged 2 commits into
mainfrom
fix-court-report-error-handling

Conversation

@compwron

@compwron compwron commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

What github issue is this PR for, if any?

Refs #7093 (the observability half — the functional fix is #7095 / the hotfix branch)

What changed, and why?

CaseCourtReportsController#generate rescued everything and passed the exception straight to the user:

rescue => e
  error_messages = generate_error(e.to_s)

That is how undefined method 'parse' for class CGI ended up being read off an office manager's screen in #7093. Two problems with it:

  1. Users see Ruby internals. Nothing in that string tells them what to do, and it looks alarming.
  2. Nobody else sees anything at all. The exception was swallowed by the rescue, so Bugsnag never heard about it. Active Storage had been failing on every attachment for weeks and the only signal we got was a stakeholder emailing to say reports were broken.

Now the exception is reported with the case number and user id attached, logged, and users get:

Something went wrong generating this report. The CASA team has been notified. Please try again in a few minutes.

One judgement call worth flagging: I also added reporting to the Zip::Error branch. It keeps its existing "Template is not found" wording, which is actionable and worth keeping, but a broken org court report template is something we'd want to hear about rather than swallow — and #7093's triage notes show template problems have bitten this org before (#1826 / #2265 / #3698). Easy to drop that hunk if you'd rather keep this PR to the one rescue.

How is this tested? (please write rspec and jest tests!) 💖💪

Extended the existing "when an unpredictable error occurs" context in spec/requests/case_court_reports_spec.rb. It now raises the actual production exception and asserts all three things that went wrong:

when an unpredictable error occurs
  is expected to respond with status code :unprocessable_content (422)
  shows a generic error message
  does not leak the exception to the user
  reports the exception to Bugsnag

Full file: 29 examples, 3 failures — all three are the pre-existing Sprockets::Rails::Helper::AssetNotPrecompiledError: Asset 'tailwind.css' was not declared to be precompiled in production failures on the index action. Verified they fail identically on unmodified main, so they are not from this change, but they do mean the court reports index spec is currently red on main and probably wants its own issue.

Screenshots please :)

No layout change — same flash component, different text. Before / after of the string a user sees:

- undefined method 'parse' for class CGI
+ Something went wrong generating this report. The CASA team has been notified. Please try again in a few minutes.

CaseCourtReportsController#generate rescued everything and passed e.to_s
straight into the flash, so when Azure blob signing broke, an office manager
read "undefined method 'parse' for class CGI" off her screen — and because the
exception was swallowed, nothing reached Bugsnag either. The outage was only
found because a stakeholder emailed.

Report the exception with case number and user id as metadata, log it, and show
users a generic message. Zip::Error keeps its actionable "Template is not
found" wording but now also reports, since a broken org template is something
we want to hear about rather than swallow.

Refs #7093

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@compwron
compwron merged commit 7d77d55 into main Aug 7, 2026
11 checks passed
@compwron
compwron deleted the fix-court-report-error-handling branch August 7, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ruby Touches Ruby code 🧪 Tests Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant