Skip to content

Commit a79041d

Browse files
Merge pull request nestjs#908 from nestjs/feature/860-default-filter
feature(@nestjs) expose default exception filters nestjs#860
2 parents 1be2ccd + dcba921 commit a79041d

32 files changed

Lines changed: 188 additions & 162 deletions
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { ArgumentsHost, ExceptionFilter, HttpException, HttpServer, HttpStatus, Logger } from '@nestjs/common';
2+
import { isObject } from '@nestjs/common/utils/shared.utils';
3+
import { messages } from '../constants';
4+
5+
export class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
6+
private static readonly logger = new Logger('ExceptionsHandler');
7+
8+
constructor(protected readonly applicationRef: HttpServer) {}
9+
10+
catch(exception: T, host: ArgumentsHost) {
11+
if (!(exception instanceof HttpException)) {
12+
const body = {
13+
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
14+
message: messages.UNKNOWN_EXCEPTION_MESSAGE,
15+
};
16+
this.applicationRef.reply(host.getArgByIndex(1), body, body.statusCode);
17+
if (this.isExceptionObject(exception)) {
18+
return BaseExceptionFilter.logger.error(
19+
exception.message,
20+
exception.stack,
21+
);
22+
}
23+
return BaseExceptionFilter.logger.error(exception as any);
24+
}
25+
const res = exception.getResponse();
26+
const message = isObject(res)
27+
? res
28+
: {
29+
statusCode: exception.getStatus(),
30+
message: res,
31+
};
32+
33+
this.applicationRef.reply(
34+
host.getArgByIndex(1),
35+
message,
36+
exception.getStatus(),
37+
);
38+
}
39+
40+
public isExceptionObject(err): err is Error {
41+
return isObject(err) && !!(err as Error).message;
42+
}
43+
}
Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,22 @@
1-
import { HttpException, HttpServer, Logger } from '@nestjs/common';
1+
import { HttpException, HttpServer } from '@nestjs/common';
22
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
33
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
4-
import { isEmpty, isObject } from '@nestjs/common/utils/shared.utils';
5-
import { messages } from '../constants';
4+
import { isEmpty } from '@nestjs/common/utils/shared.utils';
65
import { InvalidExceptionFilterException } from '../errors/exceptions/invalid-exception-filter.exception';
6+
import { BaseExceptionFilter } from './base-exception-filter';
77

8-
export class ExceptionsHandler {
9-
private static readonly logger = new Logger(ExceptionsHandler.name);
8+
export class ExceptionsHandler extends BaseExceptionFilter {
109
private filters: ExceptionFilterMetadata[] = [];
1110

12-
constructor(private readonly applicationRef: HttpServer) {}
11+
constructor(applicationRef: HttpServer) {
12+
super(applicationRef);
13+
}
1314

1415
public next(exception: Error | HttpException | any, ctx: ArgumentsHost) {
15-
if (this.invokeCustomFilters(exception, ctx)) return;
16-
17-
if (!(exception instanceof HttpException)) {
18-
const body = {
19-
statusCode: 500,
20-
message: messages.UNKNOWN_EXCEPTION_MESSAGE,
21-
};
22-
this.applicationRef.reply(ctx.getArgByIndex(1), body, body.statusCode);
23-
if (this.isExceptionObject(exception)) {
24-
return ExceptionsHandler.logger.error(
25-
exception.message,
26-
exception.stack,
27-
);
28-
}
29-
return ExceptionsHandler.logger.error(exception);
16+
if (this.invokeCustomFilters(exception, ctx)) {
17+
return void 0;
3018
}
31-
const res = exception.getResponse();
32-
const message = isObject(res)
33-
? res
34-
: {
35-
statusCode: exception.getStatus(),
36-
message: res,
37-
};
38-
39-
this.applicationRef.reply(
40-
ctx.getArgByIndex(1),
41-
message,
42-
exception.getStatus(),
43-
);
19+
super.catch(exception, ctx);
4420
}
4521

4622
public setCustomFilters(filters: ExceptionFilterMetadata[]) {
@@ -64,8 +40,4 @@ export class ExceptionsHandler {
6440
filter && filter.func(exception, response);
6541
return !!filter;
6642
}
67-
68-
public isExceptionObject(err): err is Error {
69-
return isObject(err) && !!(err as Error).message;
70-
}
7143
}

packages/core/index.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
* MIT Licensed
66
*/
77

8-
export { MiddlewareBuilder } from './middleware/builder';
8+
export * from './adapters';
9+
export { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from './constants';
10+
export { BaseExceptionFilter } from './exceptions/base-exception-filter';
911
export { ModuleRef } from './injector/module-ref';
10-
export { NestFactory } from './nest-factory';
1112
export { HTTP_SERVER_REF } from './injector/tokens';
12-
export { APP_INTERCEPTOR, APP_FILTER, APP_GUARD, APP_PIPE } from './constants';
13-
export * from './adapters';
14-
export * from './services';
13+
export { MiddlewareBuilder } from './middleware/builder';
1514
export * from './nest-application';
1615
export * from './nest-application-context';
16+
export { NestFactory } from './nest-factory';
17+
export * from './services';

packages/microservices/client/client-grpc.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Logger } from '@nestjs/common/services/logger.service';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
33
import { Observable } from 'rxjs';
4-
import { InvalidGrpcPackageException } from '../exceptions/invalid-grpc-package.exception';
5-
import { InvalidGrpcServiceException } from '../exceptions/invalid-grpc-service.exception';
6-
import { InvalidProtoDefinitionException } from '../exceptions/invalid-proto-definition.exception';
4+
import { GRPC_DEFAULT_URL } from '../constants';
5+
import { InvalidGrpcPackageException } from '../exceptions/errors/invalid-grpc-package.exception';
6+
import { InvalidGrpcServiceException } from '../exceptions/errors/invalid-grpc-service.exception';
7+
import { InvalidProtoDefinitionException } from '../exceptions/errors/invalid-proto-definition.exception';
8+
import { ClientGrpc, GrpcOptions } from '../interfaces';
79
import { ClientOptions } from '../interfaces/client-metadata.interface';
8-
import { GRPC_DEFAULT_URL } from './../constants';
9-
import { ClientGrpc, GrpcOptions } from './../interfaces';
1010
import { ClientProxy } from './client-proxy';
1111
import { GRPC_CANCELLED } from './constants';
1212

packages/microservices/client/client-mqtt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Logger } from '@nestjs/common/services/logger.service';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
3+
import { ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL } from '../constants';
34
import { MqttClient } from '../external/mqtt-client.interface';
5+
import { MqttOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
46
import { ClientOptions } from '../interfaces/client-metadata.interface';
5-
import { ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL } from './../constants';
6-
import { MqttOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
77
import { ClientProxy } from './client-proxy';
88
import { ECONNREFUSED } from './constants';
99

packages/microservices/client/client-nats.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Logger } from '@nestjs/common/services/logger.service';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
3+
import { ERROR_EVENT, NATS_DEFAULT_URL } from '../constants';
34
import { Client } from '../external/nats-client.interface';
5+
import { NatsOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
46
import { ClientOptions } from '../interfaces/client-metadata.interface';
5-
import { ERROR_EVENT, NATS_DEFAULT_URL } from './../constants';
6-
import { NatsOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
77
import { ClientProxy } from './client-proxy';
88
import { CONN_ERR } from './constants';
99

packages/microservices/client/client-proxy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { isNil } from '@nestjs/common/utils/shared.utils';
22
import { defer, fromEvent, merge, Observable, Observer, throwError as _throw } from 'rxjs';
33
import { map, mergeMap, take } from 'rxjs/operators';
44
import { CONNECT_EVENT, ERROR_EVENT } from '../constants';
5-
import { InvalidMessageException } from '../exceptions/invalid-message.exception';
6-
import { ClientOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
5+
import { InvalidMessageException } from '../exceptions/errors/invalid-message.exception';
6+
import { ClientOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
77

88
export abstract class ClientProxy {
99
public abstract connect(): Promise<any>;

packages/microservices/client/client-redis.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { Logger } from '@nestjs/common/services/logger.service';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
33
import { fromEvent, merge, Subject, zip } from 'rxjs';
44
import { take } from 'rxjs/operators';
5+
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, REDIS_DEFAULT_URL, SUBSCRIBE } from '../constants';
56
import { ClientOpts, RedisClient, RetryStrategyOptions } from '../external/redis.interface';
7+
import { PacketId, ReadPacket, RedisOptions, WritePacket } from '../interfaces';
68
import { ClientOptions } from '../interfaces/client-metadata.interface';
7-
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, REDIS_DEFAULT_URL, SUBSCRIBE } from './../constants';
8-
import { PacketId, ReadPacket, RedisOptions, WritePacket } from './../interfaces';
99
import { ClientProxy } from './client-proxy';
1010
import { ECONNREFUSED } from './constants';
1111

packages/microservices/client/client-tcp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Logger } from '@nestjs/common';
22
import * as JsonSocket from 'json-socket';
33
import * as net from 'net';
44
import { tap } from 'rxjs/operators';
5+
import { CLOSE_EVENT, ERROR_EVENT, MESSAGE_EVENT, TCP_DEFAULT_HOST, TCP_DEFAULT_PORT } from '../constants';
6+
import { PacketId, ReadPacket, WritePacket } from '../interfaces';
57
import { ClientOptions, TcpClientOptions } from '../interfaces/client-metadata.interface';
6-
import { CLOSE_EVENT, ERROR_EVENT, MESSAGE_EVENT, TCP_DEFAULT_HOST, TCP_DEFAULT_PORT } from './../constants';
7-
import { PacketId, ReadPacket, WritePacket } from './../interfaces';
88
import { ClientProxy } from './client-proxy';
99
import { ECONNREFUSED } from './constants';
1010

packages/microservices/container.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ClientProxy } from './index';
1+
import { ClientProxy } from '.';
22
import { Closeable } from './interfaces/closeable.interface';
33

44
export type CloseableClient = Closeable & ClientProxy;

0 commit comments

Comments
 (0)