Skip to content

Commit ac16d93

Browse files
author
maxbronnikov10
committed
fix(core): HTTP adapter error mapping
1 parent f2d8543 commit ac16d93

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

packages/core/router/routes-resolver.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { BadRequestException, NotFoundException } from '@nestjs/common';
1+
import {
2+
BadRequestException,
3+
HttpException,
4+
NotFoundException,
5+
} from '@nestjs/common';
26
import {
37
HOST_METADATA,
48
MODULE_PATH,
@@ -185,11 +189,24 @@ export class RoutesResolver implements Resolver {
185189
// encoding, e.g. '%FF' (#8915)
186190
case err instanceof SyntaxError || err instanceof URIError:
187191
return new BadRequestException(err.message);
192+
case this.isHttpFastifyError(err):
193+
return new HttpException(err.message, err.statusCode);
188194
default:
189195
return err;
190196
}
191197
}
192198

199+
private isHttpFastifyError(
200+
error: any,
201+
): error is Error & { statusCode: number } {
202+
// condition based on this code - https://github.com/fastify/fastify-error/blob/d669b150a82968322f9f7be992b2f6b463272de3/index.js#L22
203+
return (
204+
error.statusCode !== undefined &&
205+
error instanceof Error &&
206+
error.name === 'FastifyError'
207+
);
208+
}
209+
193210
private getModulePathMetadata(metatype: Type<unknown>): string | undefined {
194211
const modulesContainer = this.container.getModules();
195212
const modulePath = Reflect.getMetadata(

packages/core/test/router/routes-resolver.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
BadRequestException,
3+
HttpException,
34
Module,
45
Post,
56
VersioningType,
@@ -17,6 +18,7 @@ import { GraphInspector } from '../../inspector/graph-inspector';
1718
import { SerializedGraph } from '../../inspector/serialized-graph';
1819
import { RoutesResolver } from '../../router/routes-resolver';
1920
import { NoopHttpAdapter } from '../utils/noop-adapter.spec';
21+
import { createError } from '@fastify/error';
2022

2123
describe('RoutesResolver', () => {
2224
@Controller('global')
@@ -334,6 +336,35 @@ describe('RoutesResolver', () => {
334336
expect(outputErr).to.be.instanceof(BadRequestException);
335337
});
336338
});
339+
describe('FastifyError', () => {
340+
it('should map FastifyError with status code to HttpException', () => {
341+
const FastifyErrorCls = createError(
342+
'FST_ERR_CTP_INVALID_MEDIA_TYPE',
343+
'Unsupported Media Type: %s',
344+
415,
345+
);
346+
const error = new FastifyErrorCls();
347+
348+
const result = routesResolver.mapExternalException(error);
349+
350+
expect(result).to.be.instanceOf(HttpException);
351+
expect(result.message).to.equal(error.message);
352+
expect(result.getStatus()).to.equal(415);
353+
});
354+
355+
it('should return FastifyError without user status code to Internal Server Error HttpException', () => {
356+
const FastifyErrorCls = createError(
357+
'FST_WITHOUT_STATUS_CODE',
358+
'Error without status code',
359+
);
360+
const error = new FastifyErrorCls();
361+
362+
const result = routesResolver.mapExternalException(error);
363+
expect(result).to.be.instanceOf(HttpException);
364+
expect(result.message).to.equal(error.message);
365+
expect(result.getStatus()).to.equal(500);
366+
});
367+
});
337368
describe('other', () => {
338369
it('should behave as an identity', () => {
339370
const err = new Error();

0 commit comments

Comments
 (0)