NestJS:异常处理的最佳做法(异常过滤器与Interceptors.catchError)

时间:2019-01-28 16:22:08

标签: exception exception-handling nestjs

Exception filters上使用Interceptors.catchError的利弊是什么。 (异常映射)?

1 个答案:

答案 0 :(得分:0)

不确定您是否已经找到答案,但是就我的实现而言,以下情况使用过滤器或拦截器

异常过滤器:

异常过滤器是一种捕获从应用程序抛出的错误的机制,无论是在加载模块或启动请求时,它们都是捕获问题(尤其是运行时错误)的最佳方案。

请考虑一个方案,其中您已实现的自定义记录器服务(例如pino记录器服务)具有一个如下所示的编辑路径: (注意:loggerService应该已经定义了实现的方法。现在,我留空)

@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 {
    }

}

这是示例摘要path: [req.headers["Contet-typr"] 现在,编校路径显然是不正确的,但是除非做出特定要求并且该记录器在某处实现,否则无法确定。

请考虑一个场景,其中存在被设置为全局拦截器的拦截器(例如日志记录拦截器)。下面的一个是日志记录拦截器,它尝试删除“ content-type”标头,但是由于修改后的数组路径不正确,因此将导致抛出运行时异常。

@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();
    }

}

捕获这些异常的方法是通过异常过滤器,而不是通过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));
    }

}

希望这会有所帮助。