Reputation: 71
What are pros and cons using Exception filters over Interceptors.catchError . (Exception mapping)?
Upvotes: 7
Views: 3759
Reputation: 1177
Not sure if you have already have the answer, but as far as my implementation goes, the following scenarios use either filters or interceptors
Exception Filters:
exception filters are a mechanism to capture the errors thrown from the app/ be it when the modules are loaded or request being initiated, they are the best case scenario to capture the issues especially runtime errors.
Consider a scenario where the custom logger service you have implemented, (say a pino logger service), has a redact path like this: (note: loggerService should have defined the implemented methods. For now, I am leaving empty)
@Injectable({
scope: Scope.DEFAULT
})
export class PinoLoggerService implements LoggerService{
constructor(private appUtilService: AppUtilService) {
}
logService = (fileNameString): pino.Logger => {
return pino({
useLevelLabels: true,
prettyPrint: this.appUtilService.isDevEnv(),
// tslint:disable-next-line: object-literal-sort-keys
messageKey: APP_MESSAGE_KEY,
level: this.appUtilService.getLogLevel(),
redact: {
paths: APP_LOG_REDACT,
censor: '**SECRET-INFO**'
},
base: {
hostName: os.hostname(),
platform: os.platform(),
processId: process.pid,
timestamp: this.appUtilService.getCurrentLocaleTimeZone(),
// tslint:disable-next-line: object-literal-sort-keys
fileName: this.appUtilService.getFileName(fileNameString),
},
});
}
debug(message: any, context?: string): any {
}
error(message: any, trace?: string, context?: string): any {
}
log(message: any, context?: string): any {
}
warn(message: any, context?: string): any {
}
}
This is a sample redact path: [req.headers["Contet-typr"]
Now the redact path is incorrect obviously, but cannot be determined unless a specific req is made and that logger is implemented somewhere.
Consider a scenario where there are interceptors (example like logging interceptor) which is set as global interceptor. The one below is a logging interceptor which tries to redact the "content-type" header but since the redact array path is incorrect, this will result in a run time exception being thrown.
@Injectable()
export class LoggingInterceptor implements NestInterceptor{
constructor(private readonly logService: PinoLoggerService) {
}
intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {
const headers = context.switchToHttp().getRequest().headers;
console.log('Logging the incoming req', headers);
return next.handle();
}
}
And the way to capture these exceptions is via the exception filter and not via Interceptor.catchError
export class CustomExceptionFilter implements ExceptionFilter {
catch(exception: any, host: ArgumentsHost): any {
console.log('coming in first filter');
const errModel = new ErrorModel('AppErrorType');
errModel.name = exception.name;
errModel.errorMessage = exception.message;
errModel.errorCode = '500';
errModel.errorFields = null;
errModel.reason = 'Internal server failure';
errModel.stack = exception.stack;
exception['errorModel'] = errModel;
console.log('exce:', exception);
const reply: FastifyReply<any> = host.switchToHttp().getResponse();
reply.send({error: errModel}).status(parseInt(errModel.errorCode));
}
}
Hope this helps.
Upvotes: 2