Skip to content

Return 400 for malformed work history JSON#456

Merged
ralyodio merged 1 commit into
profullstack:masterfrom
rissrice2105-agent:codex/work-history-json-400
Jun 14, 2026
Merged

Return 400 for malformed work history JSON#456
ralyodio merged 1 commit into
profullstack:masterfrom
rissrice2105-agent:codex/work-history-json-400

Conversation

@rissrice2105-agent

Copy link
Copy Markdown
Contributor

Fixes #455.

Summary

  • Return 400 for malformed JSON sent to POST /api/work-history
  • Prevent invalid request bodies from reaching work history validation or inserts
  • Add regression coverage for malformed JSON

Verification

  • vitest run src/app/api/work-history/route.test.ts
  • tsc --noEmit

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown

Greptile Summary

Adds a try/catch around request.json() in POST /api/work-history so malformed request bodies are rejected with a 400 before reaching schema validation or any database call, and adds a matching regression test.

  • route.ts: wraps request.json() in an inner try/catch that returns { error: "Invalid JSON body" } with status 400 on failure; the rest of the handler (auth, validation, DB insert) is unchanged.
  • route.test.ts: new test mocks auth context, passes a fake request whose json() rejects with SyntaxError, and asserts status 400, the correct error message, and that the Supabase from method is never invoked.

Confidence Score: 4/5

Safe 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 request.json() as a client 400, which could mask infrastructure failures that should surface as 500 — unlikely in practice but worth narrowing.

The inner catch in route.ts lines 43-47 is the only spot worth a second look.

Important Files Changed

Filename Overview
src/app/api/work-history/route.ts Adds an inner try/catch around request.json() to return 400 for malformed JSON before validation or DB access; catch is broad (catches all errors, not just SyntaxError).
src/app/api/work-history/route.test.ts New regression test for malformed JSON — mocks auth context, passes a request whose json() rejects with SyntaxError, and asserts 400 status, correct error message, and no DB calls.

Sequence Diagram

sequenceDiagram
    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 }"
Loading

Reviews (1): Last reviewed commit: "Handle malformed work history JSON" | Re-trigger Greptile

Comment on lines +43 to +47
try {
body = await request.json();
} catch {
return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 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.

Suggested change
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 });
}

@rissrice2105-agent

Copy link
Copy Markdown
Contributor Author

CI is green for PR #456.

Verification:

  • vitest run src/app/api/work-history/route.test.ts
  • tsc --noEmit

uGig invoice evidence will be sent after the duplicate-invoice retry window for the same gig/application has elapsed.

@rissrice2105-agent

Copy link
Copy Markdown
Contributor Author

Invoice evidence has now been sent for PR #456.

CI is green and local verification was:

  • vitest run src/app/api/work-history/route.test.ts
  • tsc --noEmit

@ralyodio ralyodio merged commit 9db02d6 into profullstack:master Jun 14, 2026
6 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.

POST /api/work-history returns 500 for malformed JSON bodies

2 participants