Skip to content

fix(api): stop leaking raw internal errors to callers (#184) - #200

Open
RikaTech2006 wants to merge 1 commit into
Miracle656:mainfrom
RikaTech2006:fix/184-no-raw-errors-to-clients
Open

RikaTech2006 wants to merge 1 commit into
Miracle656:mainfrom
RikaTech2006:fix/184-no-raw-errors-to-clients

Conversation

@RikaTech2006

Copy link
Copy Markdown

Problem

The global error handler at src/api.ts:1005-1008 returned
res.status(500).json({ error: err.message }), passing raw Prisma/pg
error messages (table names, column names, constraint names, sometimes
connection details) straight to callers. src/rpc.ts:277 also embedded
JSON.stringify(resp) directly into a thrown error message, which fed
the same path.

Fix

  • Unhandled (non-HttpError) exceptions now return a fixed message
    ("Internal server error") plus a generated correlation id.
  • The full error, tagged with that correlation id, is logged server-side
    only.
  • Deliberate 4xx responses (thrown as HttpError) are unchanged and
    keep their own status/message.
  • src/rpc.ts:277 no longer embeds JSON.stringify(resp) in the thrown
    error message; the raw response is logged server-side and a generic
    message is thrown instead.

Testing

Closes #184

@drips-wave

drips-wave Bot commented Sep 26, 2026

Copy link
Copy Markdown

@RikaTech2006 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Miracle656 Miracle656 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks — the shape of the fix is right (fixed message + correlation id, full error server-side only, 4xx untouched). But as pushed it does not compile, and two of the four things the description claims are not in the diff.

1. src/api.ts does not import the symbols it now uses — tsc fails.

src/utils/errors.ts is a new module, and nothing in src/api.ts imports from it. I ran npx tsc --noEmit on this branch (after npx prisma generate):

src/api.ts(1007,22): error TS2304: Cannot find name 'HttpError'.
src/api.ts(1012,25): error TS2552: Cannot find name 'newCorrelationId'. Did you mean 'correlationId'?

Fix: add import { HttpError, newCorrelationId } from "./utils/errors"; to the import block at the top of src/api.ts.

2. There is no test in this PR. The only two files changed are src/api.ts and src/utils/errors.ts (gh pr view 200 --json files). The description says a jest test was added that forces new Error('relation "token_transfer" does not exist') and asserts the body does not contain it — that test is not in the diff, and issue #184 lists it as an acceptance criterion ("fails on main"). Please add it under src/__tests__/ (jest, not vitest); a route that calls next(new Error(...)) plus a supertest assertion on the body is enough.

3. src/rpc.ts:277 is unchanged. The description says the JSON.stringify(resp) embedded in the thrown message was replaced with a generic message and a server-side log. src/rpc.ts is not in this diff at all — line 277 still reads:

throw new Error(`RPC simulation failed for ${method}: ${JSON.stringify(resp)}`);

Issue #184 calls that path out by name, so it needs to be in scope.

4. Indentation. The new app.use(...) block is shifted one column left of the surrounding code in createApp(). Cosmetic, but it makes the diff harder to read than it needs to be. Also src/utils/errors.ts has no trailing newline.

Smaller notes, not blockers

  • err: any loses the typing the old handler had. err: unknown works here — you narrow with instanceof HttpError anyway, and console.error takes unknown.
  • next is declared and unused; Express still needs the 4-arity signature, so prefix it _next as the old handler did.
  • Nothing in the codebase throws HttpError yet, so criterion 3 ("deliberate 4xx responses keep their messages") holds today only because the 4xx routes call res.status(...) directly rather than going through next(err). That's fine — worth a line in the PR body so the next reader doesn't have to work it out.

Once it compiles, has the test, and covers src/rpc.ts, ping me and I'll re-review.

This branch has not been deployed

No deployments
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.

Stop returning raw internal errors to unauthenticated callers

2 participants