fix(api): safe BigInt parse — 400 on bad cursor instead of 500 crash#12
Merged
Conversation
Five endpoints did raw BigInt(req.query.*) / BigInt(req.params.*):
native.ts: /blocks?before=... /blocks/:height
coinblast.ts: /coinblast/tokens?before=...
/coinblast/trades?before=...
/coinblast/trades/by-curve/:curve?after=...
When user passes non-numeric input (e.g. ?before=abc), BigInt() throws
SyntaxError. Fastify catches and returns 500 internal server error with
no actionable message. Should be 400 bad request.
Fix: parseBigIntOrThrow helper wraps BigInt() in try/catch + throws an
InvalidQueryError class. Each route catches the error and returns
400 with field-named message. Internal 500s drop, user gets
actionable error, alerter stays quiet.
Per-route handler signature changes: routes that previously didn't
accept reply now do (added 'reply' param to enable code(400) calls).
tsc --noEmit clean across both files.
This was referenced May 7, 2026
satyakwok
added a commit
that referenced
this pull request
May 7, 2026
Same class as #12 — ${threshold}::numeric in the underlying SQL was dropping bad input straight to Postgres. 'abc' returned a 22P02 500 ('invalid input syntax for type numeric') instead of a clean 400. Drizzle's sql`` parameterizes so this isn't an injection path (verified — semicolons go through as parameter values, no DROP), just a leak of internal Postgres error codes + alerter noise. Reuse parseBigIntOrThrow — wei thresholds are integers anyway, no decimal needed. Bad threshold now returns 400 with a clear message. Co-authored-by: satyakwok <satyakwok@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
Five endpoints did raw
BigInt(req.query.*)/BigInt(req.params.*):/blocks?before=.../blocks/:height/coinblast/tokens?before=.../coinblast/trades?before=.../coinblast/trades/by-curve/:curve?after=...When user passes non-numeric input (
?before=abc),BigInt()throwsSyntaxError. Fastify returns 500 with no actionable message + alerter noise.Fix
parseBigIntOrThrowhelper wrapsBigInt()in try/catch + throwsInvalidQueryError. Each route catches + returns 400 with field-named message. Defined in both route files (small enough to inline).Verified
tsc --noEmitclean.