mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
Merge pull request #14753 from glebbash/fix/stricter-is-http-error-check
fix(core): make `isHttpError` check stricter
This commit is contained in:
@@ -79,10 +79,28 @@ export class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the thrown error comes from the "http-errors" library.
|
||||
* Checks if the thrown error is a FastifyError or comes from the "http-errors" library.
|
||||
* @param err error object
|
||||
*/
|
||||
public isHttpError(err: any): err is { statusCode: number; message: string } {
|
||||
return err?.statusCode && err?.message;
|
||||
if (!err || typeof err !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
err.constructor.name === 'FastifyError' &&
|
||||
typeof err.code === 'string' &&
|
||||
typeof err.statusCode === 'number'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// "http-errors" error signature
|
||||
return (
|
||||
typeof err.expose === 'boolean' &&
|
||||
typeof err.statusCode === 'number' &&
|
||||
err.status === err.statusCode &&
|
||||
err instanceof Error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { InvalidExceptionFilterException } from '../../errors/exceptions/invalid
|
||||
import { ExceptionsHandler } from '../../exceptions/exceptions-handler.js';
|
||||
import { ExecutionContextHost } from '../../helpers/execution-context-host.js';
|
||||
import { NoopHttpAdapter } from '../utils/noop-adapter.js';
|
||||
import fastifyErrors from '@fastify/error';
|
||||
|
||||
describe('ExceptionsHandler', () => {
|
||||
let adapter: AbstractHttpAdapter;
|
||||
@@ -53,6 +54,62 @@ describe('ExceptionsHandler', () => {
|
||||
message: 'Internal server error',
|
||||
});
|
||||
});
|
||||
it('should treat fastify errors as http errors', () => {
|
||||
const fastifyError = fastifyErrors.createError(
|
||||
'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
"Body cannot be empty when content-type is set to 'application/json'",
|
||||
400,
|
||||
)();
|
||||
handler.next(fastifyError, new ExecutionContextHost([0, response]));
|
||||
|
||||
expect(statusStub).toHaveBeenCalledWith(400);
|
||||
expect(jsonStub).toHaveBeenCalledWith({
|
||||
statusCode: 400,
|
||||
message:
|
||||
"Body cannot be empty when content-type is set to 'application/json'",
|
||||
});
|
||||
});
|
||||
it('should not treat errors from external API calls as errors from "http-errors" library', () => {
|
||||
const apiCallError = Object.assign(
|
||||
new Error('Some external API call failed'),
|
||||
{ status: 400 },
|
||||
);
|
||||
handler.next(apiCallError, new ExecutionContextHost([0, response]));
|
||||
|
||||
expect(statusStub).toHaveBeenCalledWith(500);
|
||||
expect(jsonStub).toHaveBeenCalledWith({
|
||||
statusCode: 500,
|
||||
message: 'Internal server error',
|
||||
});
|
||||
});
|
||||
it('should treat fastify errors as http errors', () => {
|
||||
const fastifyError = fastifyErrors.createError(
|
||||
'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
"Body cannot be empty when content-type is set to 'application/json'",
|
||||
400,
|
||||
)();
|
||||
handler.next(fastifyError, new ExecutionContextHost([0, response]));
|
||||
|
||||
expect(statusStub).toHaveBeenCalledWith(400);
|
||||
expect(jsonStub).toHaveBeenCalledWith({
|
||||
statusCode: 400,
|
||||
message:
|
||||
"Body cannot be empty when content-type is set to 'application/json'",
|
||||
});
|
||||
});
|
||||
it('should not treat errors from external API calls as errors from "http-errors" library', () => {
|
||||
const apiCallError = Object.assign(
|
||||
new Error('Some external API call failed'),
|
||||
{ status: 400 },
|
||||
);
|
||||
handler.next(apiCallError, new ExecutionContextHost([0, response]));
|
||||
|
||||
expect(statusStub).toHaveBeenCalledWith(500);
|
||||
expect(jsonStub).toHaveBeenCalledWith({
|
||||
statusCode: 500,
|
||||
message: 'Internal server error',
|
||||
});
|
||||
});
|
||||
describe('when exception is instantiated by "http-errors" library', () => {
|
||||
it('should send expected response status code and message', () => {
|
||||
const error = new createHttpError.NotFound('User does not exist');
|
||||
|
||||
Reference in New Issue
Block a user