codex/backend-architecture-refactor #48
@ -0,0 +1,67 @@
|
||||
import { ArgumentsHost, BadRequestException, HttpStatus } from '@nestjs/common';
|
||||
import { HttpExceptionFilter } from './http-exception.filter';
|
||||
|
||||
describe('HttpExceptionFilter', () => {
|
||||
const createHost = () => {
|
||||
const json = vi.fn();
|
||||
const status = vi.fn(() => ({ json }));
|
||||
const host = {
|
||||
switchToHttp: () => ({
|
||||
getResponse: () => ({ status }),
|
||||
getRequest: () => ({ url: '/api/v1/test' }),
|
||||
}),
|
||||
} as unknown as ArgumentsHost;
|
||||
|
||||
return { host, status, json };
|
||||
};
|
||||
|
||||
it('does not expose internal Error.message for unhandled exceptions', () => {
|
||||
const filter = new HttpExceptionFilter();
|
||||
const { host, status, json } = createHost();
|
||||
|
||||
filter.catch(new Error('Prisma failed at file:///secret/path'), host);
|
||||
|
||||
expect(status).toHaveBeenCalledWith(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(json).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
message: 'Internal server error',
|
||||
error: 'Internal Server Error',
|
||||
path: '/api/v1/test',
|
||||
}),
|
||||
);
|
||||
expect(json.mock.calls[0][0].message).not.toContain('Prisma failed');
|
||||
});
|
||||
|
||||
it('returns safe defaults for non-Error thrown values', () => {
|
||||
const filter = new HttpExceptionFilter();
|
||||
const { host, status, json } = createHost();
|
||||
|
||||
filter.catch('some string error', host);
|
||||
|
||||
expect(status).toHaveBeenCalledWith(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(json).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
message: 'Internal server error',
|
||||
error: 'Internal Server Error',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps HttpException response messages intact', () => {
|
||||
const filter = new HttpExceptionFilter();
|
||||
const { host, status, json } = createHost();
|
||||
|
||||
filter.catch(new BadRequestException('Invalid request'), host);
|
||||
|
||||
expect(status).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
|
||||
expect(json).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
statusCode: HttpStatus.BAD_REQUEST,
|
||||
message: 'Invalid request',
|
||||
error: 'Bad Request',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -26,8 +26,9 @@ export class HttpExceptionFilter implements ExceptionFilter {
|
||||
error = (r.error as string) || exception.name;
|
||||
}
|
||||
} else if (exception instanceof Error) {
|
||||
message = exception.message;
|
||||
this.logger.error(`Unhandled exception: ${exception.message}`, exception.stack);
|
||||
} else {
|
||||
this.logger.error(`Unhandled non-error exception: ${String(exception)}`);
|
||||
}
|
||||
|
||||
response.status(status).json({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user