Return 400 for malformed work history JSON#456
Conversation
Greptile SummaryAdds a
Confidence Score: 4/5Safe to merge; the change is minimal and well-targeted, with a regression test covering the fixed path. The change correctly stops malformed JSON from reaching validation and the database. The bare catch treats any error from The inner catch in Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant POST as POST /api/work-history
participant Auth as getAuthContext
participant DB as Supabase
Client->>POST: POST with malformed JSON
POST->>Auth: getAuthContext(request)
Auth-->>POST: "{ user, supabase }"
POST->>POST: request.json() throws SyntaxError
POST-->>Client: "400 { error: Invalid JSON body }"
Client->>POST: POST with valid JSON
POST->>Auth: getAuthContext(request)
Auth-->>POST: "{ user, supabase }"
POST->>POST: request.json() returns body
POST->>POST: workHistorySchema.safeParse(body)
POST->>DB: insert work_history
DB-->>POST: "{ data, error }"
POST-->>Client: "201 { work_history }"
Reviews (1): Last reviewed commit: "Handle malformed work history JSON" | Re-trigger Greptile |
| try { | ||
| body = await request.json(); | ||
| } catch { | ||
| return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); | ||
| } |
There was a problem hiding this comment.
Bare catch swallows all
json() errors as 400
The inner catch catches every possible error from request.json(), not just SyntaxError. In normal operation this is fine, but if the body stream has already been consumed or there's some other infrastructure-level failure, the endpoint will silently return 400 instead of letting the outer catch promote it to 500. Narrowing the catch to SyntaxError is the standard pattern and keeps 500-class failures from being misclassified.
| try { | |
| body = await request.json(); | |
| } catch { | |
| return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); | |
| } | |
| try { | |
| body = await request.json(); | |
| } catch (err) { | |
| if (!(err instanceof SyntaxError)) throw err; | |
| return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); | |
| } |
|
CI is green for PR #456. Verification:
uGig invoice evidence will be sent after the duplicate-invoice retry window for the same gig/application has elapsed. |
|
Invoice evidence has now been sent for PR #456. CI is green and local verification was:
|
Fixes #455.
Summary
POST /api/work-historyVerification
vitest run src/app/api/work-history/route.test.tstsc --noEmit