Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/presentation/http/http-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import UploadRouter from './router/upload.js';
import { ajvFilePlugin } from '@fastify/multipart';
import { UploadSchema } from './schema/Upload.js';
import { NoteHierarchySchema } from './schema/NoteHierarchy.js';
import { StatusCodes } from 'http-status-codes';

const appServerLogger = getLogger('appServer');

Expand Down Expand Up @@ -372,6 +373,21 @@ export default class HttpApi implements Api {

return;
}
/**
* JSON parse errors (invalid request body)
*/
if (error instanceof SyntaxError && error.message.includes('JSON')) {
Comment on lines +377 to +379
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The JSON-parse branch matches any SyntaxError whose message contains "JSON", which can inadvertently convert server-side JSON.parse bugs into 400 responses and make them harder to detect. Consider narrowing the condition to Fastify body-parser errors (e.g., check error.statusCode === 400 and/or a Fastify-specific error.code/body marker) so only invalid request bodies are handled here.

Suggested change
* JSON parse errors (invalid request body)
*/
if (error instanceof SyntaxError && error.message.includes('JSON')) {
* JSON parse errors from Fastify body parser (invalid request body)
*/
if (
(error as any)?.statusCode === StatusCodes.BAD_REQUEST &&
typeof (error as any)?.code === 'string' &&
(error as any).code.startsWith('FST_ERR_CTP_')
) {

Copilot uses AI. Check for mistakes.
this.log.warn({ reqId: request.id }, 'Invalid JSON in request body');

return reply
.code(StatusCodes.BAD_REQUEST)
.type('application/json')
.send({
message: 'Invalid JSON in request body',
error: 'Bad Request',
statusCode: StatusCodes.BAD_REQUEST,
Comment on lines +387 to +388
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

This 400 response body includes error and statusCode, but other API error helpers in this codebase (e.g., reply.domainError, reply.unauthorized, etc.) return { message }, and ErrorResponse only defines code/message (src/presentation/http/types/HttpResponse.ts). To keep client error handling consistent, consider sending the same shape here (likely just { message }, or { code, message } if you want an app-level code).

Suggested change
error: 'Bad Request',
statusCode: StatusCodes.BAD_REQUEST,

Copilot uses AI. Check for mistakes.
});
Comment on lines +376 to +389
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

New behavior in the global error handler should be covered by tests. There is existing Vitest coverage for HTTP routes using global.api.fakeRequest (e.g., src/presentation/http/router/*.test.ts); please add a test that sends invalid JSON with content-type: application/json and asserts the API returns 400 with the expected error payload.

Copilot uses AI. Check for mistakes.
}
/**
* If error is not a domain error, we route it to the default error handler
*/
Expand Down
Loading