Summary
The React frontend has no error boundary component. Any unhandled
JavaScript error in a component — a failed API response parsed
incorrectly, a null reference on a missing ballot field, a type
mismatch in the vote submission form — causes the entire React tree
to unmount and displays a completely blank white screen with no message
and no recovery path. This is particularly bad for voters mid-submission
who have no indication whether their vote was cast or whether something
went wrong.
The 28 existing tests cover component logic but none test error
boundary behavior because no error boundary exists to test.
Scope
- Create an
ErrorBoundary class component in
frontend/src/components/ErrorBoundary.tsx that catches unhandled
errors in the React tree and renders a fallback UI instead of a
blank screen
- The fallback UI should display a clear message, a button to reload
the page, and a note that if the voter was mid-submission they
should contact the ballot organiser to verify their vote status
- Wrap the root
App component in ErrorBoundary so the entire
application is covered
- Add a more specific
ErrorBoundary around the vote submission form
specifically — this is the highest-stakes UI and needs its own
isolated boundary with a tailored fallback message
- Add a unit test that mounts a component that throws, confirms the
error boundary catches it, and verifies the fallback UI renders
with the correct message
- Add
console.error suppression in the test to avoid noise from
intentional error throwing
Relevant Files
frontend/src/components/ErrorBoundary.tsx (new file)
frontend/src/App.tsx
frontend/src/pages/ (vote submission page)
frontend/src/tests/
Acceptance Criteria
Out of Scope
- Error reporting to an external service — a separate issue
- Backend error handling — a separate issue
Note for Contributors
The fallback message on the vote submission boundary is important to
get right. A voter who sees a blank screen mid-submission will not
know if their vote was counted. The fallback must tell them explicitly
to contact the organiser to check — do not leave them uncertain.
Summary
The React frontend has no error boundary component. Any unhandled
JavaScript error in a component — a failed API response parsed
incorrectly, a null reference on a missing ballot field, a type
mismatch in the vote submission form — causes the entire React tree
to unmount and displays a completely blank white screen with no message
and no recovery path. This is particularly bad for voters mid-submission
who have no indication whether their vote was cast or whether something
went wrong.
The 28 existing tests cover component logic but none test error
boundary behavior because no error boundary exists to test.
Scope
ErrorBoundaryclass component infrontend/src/components/ErrorBoundary.tsxthat catches unhandlederrors in the React tree and renders a fallback UI instead of a
blank screen
the page, and a note that if the voter was mid-submission they
should contact the ballot organiser to verify their vote status
Appcomponent inErrorBoundaryso the entireapplication is covered
ErrorBoundaryaround the vote submission formspecifically — this is the highest-stakes UI and needs its own
isolated boundary with a tailored fallback message
error boundary catches it, and verifies the fallback UI renders
with the correct message
console.errorsuppression in the test to avoid noise fromintentional error throwing
Relevant Files
frontend/src/components/ErrorBoundary.tsx(new file)frontend/src/App.tsxfrontend/src/pages/(vote submission page)frontend/src/tests/Acceptance Criteria
ErrorBoundarycomponent implemented as a React class componentAppwrapped inErrorBoundaryErrorBoundarywitha tailored fallback message referencing vote status verification
message — not a technical error code
Out of Scope
Note for Contributors
The fallback message on the vote submission boundary is important to
get right. A voter who sees a blank screen mid-submission will not
know if their vote was counted. The fallback must tell them explicitly
to contact the organiser to check — do not leave them uncertain.