可以使用 Nestjs 的异常过滤器处理多个错误吗?

Can handle multiple errors using Nestjs' Exception Filter?

Spring 引导能够使用@RestControllerAdvice 处理各种错误。 springboot创建的代码如下

@RestControllerAdvice
public class ControllerExceptionHandler {

    // @valid에서 바인딩 에러가 발생
    @ExceptionHandler(MethodArgumentNotValidException.class)
    protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("handleMethodArgumentNotValidException ==> " + e);
        final ErrorResponse response = ErrorResponse.of(ErrorCode.WRONG_INPUT_VALUE, e.getBindingResult());
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }

    // 사용자 생성시 이메일이 중복된 경우
    @ExceptionHandler(DuplicateEmailException.class)
    public ResponseEntity<ErrorResponse> handleDuplicateEmailException(DuplicateEmailException e) {
        log.error("handleDuplicateEmailException ==> " + e);
        final ErrorResponse response = ErrorResponse.of(ErrorCode.DUPLICATE_EMAIL_VALUE);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }

    ...
}

目前,我在使用 NestJs 处理错误时寻找类似于@RestControllerAdvice 的功能,并且发现了 ExceptionFilter。代码是我写的,但是写完之后有一个疑问。如果我们这样处理错误,我们只能处理与HttPexception相关的错误,对吧?

我想全局处理除 HttPexception 之外的其他错误。但是,与 Spring Boot 的 @RestControllerAdvice 不同,ExceptionFilter 似乎无法在单个 class 中处理许多错误。我用错了吗?

@Catch()
export class ExceptionHandler implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        const status = exception.getStatus();

        response.status(status).json({
            statusCode: status,
            message: exception.message,
            path: request.url
        });
    }
}

您必须将异常 class 传递给 @Catch() 装饰器。 如果你想捕获所有的 http 异常你可以做

import { ExceptionFilter, Catch } from '@nestjs/common';

@Catch(HttpException)
export class ExceptionHandler implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        const status = exception.getStatus();

        response.status(status).json({
            statusCode: status,
            message: exception.message,
            path: request.url
        });
    }
}

这将捕获执行任何路由时抛出的所有错误。

您还可以传递一些异常 classes 以仅捕获特定的异常。

 @Catch(BadRequestException, UnauthorizedException)

您可以在 https://docs.nestjs.com/exception-filters

阅读更多内容