Skip to content

fix(errors): report an unhandled error as 500 rather than 404 - #239

Merged
Bccorb merged 1 commit into
mainfrom
fix/unhandled-errors-return-500
Aug 31, 2026
Merged

fix(errors): report an unhandled error as 500 rather than 404#239
Bccorb merged 1 commit into
mainfrom
fix/unhandled-errors-return-500

Conversation

@Bccorb

@Bccorb Bccorb commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Closes #230.

-    return next();
+    return next(err);

Calling next() with no argument from an error-handling middleware clears the error and resumes at the next regular middleware. That skipped the 500 handler sitting directly below and landed on the 404, so every unhandled exception was reported to the caller as 404 {"error":"Not Found"}.

Why this mattered more than the status code

The 404 handler logs an AuthEventService.requestSuspicious event with reason "Request to an unknown route." So each internal fault was written into the anomaly signal the dashboard and the security views read, attributed to whoever happened to send the request. Server bugs were polluting the stream meant for hostile callers, and doing it precisely when the server was misbehaving. There is now a test asserting a server error records nothing.

The second consequence is that a 500 is alertable and a 404 on an auth API is background noise. This masked a genuine regression through a full test run during the Express 5 work.

Contract change and blast radius

A request that triggers an unhandled exception now answers 500 {"error":"Internal server error"} instead of 404 {"error":"Not Found"}. A genuinely unmatched route still answers 404, unchanged. Callers that retry on 5xx but not 4xx will now retry these.

Surveyed the dependents before committing:

  • seamless-auth-react: no 404 branching anywhere in src. Unaffected.
  • seamless-auth-server: the only 404 reference is a comment in the fastify console proxy about method handling. Unaffected.
  • seamless-auth-admin-dashboard: handles both, and this is an improvement. friendlyStatusMessage mapped these to "The requested resource was not found." and will now say "The Seamless Auth API had a problem. Try again shortly." Its MESSAGE_SURFACING_STATUSES deliberately excludes 5xx, and the 500 body is generic, so nothing upstream leaks.

No coordinated release needed.

On the existing test

passes non-CORS errors through to the not-found handler pinned the old 404, which is why I raised this as a question rather than assuming it was a bug. Replaced with one asserting the 500, plus one asserting the suspicious event is not recorded.

Verification

Exactly one existing test moved, the one that pinned the behaviour. Full suite 1195 passed, 1 skipped. minor changeset per the pre-1.0 rule, describing the break in the body.

The first error handler answered the CORS rejection and passed everything else
on with a bare next(). From an error handler that clears the error and resumes
at the next regular middleware, so the 500 handler directly below was skipped
and control landed on the 404. Every unhandled exception was reported to the
caller as 404 Not Found.

The 404 handler also logs a requestSuspicious event, so each internal error was
written into the anomaly signal as suspicious behaviour by whoever sent the
request. Routing errors to the 500 handler takes them out of that stream.

A genuinely unmatched route still answers 404. Surveyed the dependents: the
React SDK does not branch on 404 at all, the server adapter's only reference is
an unrelated comment, and the admin dashboard already maps 5xx to a clearer
message than the 404 text it was getting.
@Bccorb
Bccorb merged commit bbb7fac into main Aug 31, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(errors): unhandled errors answer 404 instead of 500

1 participant