繁体   English   中英

什么是 Nestjs 错误处理方法(业务逻辑错误与 http 错误)?

[英]What is the nestjs error handling approach (business logic error vs. http error)?

在使用 NestJS 创建 API 时,我想知道哪种是处理错误/异常的最佳方式。 我发现了两种不同的方法:

  1. 让单个服务和验证管道throw new Error() ,让控制器catch它们,然后抛出适当类型的HttpExceptionBadRequestExceptionForbiddenException等。)
  2. 让控制器简单地调用负责处理该部分业务逻辑的服务/验证管道方法,并抛出适当的HttpException

这两种方法各有利弊:

  1. 这似乎是正确的方法,但是,服务可能会因不同的原因返回Error ,我如何从控制器知道哪个是相应类型的HttpException返回?
  2. 非常灵活,但在服务中使用Http相关的东西似乎是错误的。

我想知道,哪一种(如果有的话)是“嵌套 js”的做法?

你怎么处理这件事?

假设您的业务逻辑抛出EntityNotFoundError并且您希望将其映射到NotFoundException

为此,您可以创建一个Interceptor来转换您的错误:

@Injectable()
export class NotFoundInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // next.handle() is an Observable of the controller's result value
    return next.handle()
      .pipe(catchError(error => {
        if (error instanceof EntityNotFoundError) {
          throw new NotFoundException(error.message);
        } else {
          throw error;
        }
      }));
  }
}

然后,您可以通过将@UseInterceptors(NotFoundInterceptor)添加到控制器的类或方法中来使用它; 甚至作为所有路由的全局拦截器。 当然,您也可以在一个拦截器中映射多个错误。

在这个codeandbox 中尝试一下。

您可能不仅希望将服务绑定到 HTTP 接口,还希望绑定到 GraphQL 或任何其他接口。 因此最好将业务逻辑级别的异常从服务转换为控制器中的 Http 级别异常(BadRequestException、ForbiddenException)。

以最简单的方式,它看起来像

import { BadRequestException, Injectable } from '@nestjs/common';

@Injectable()
export class HttpHelperService {
  async transformExceptions(action: Promise<any>): Promise<any> {
    try {
      return await action;
    } catch (error) {
      if (error.name === 'QueryFailedError') {
        if (/^duplicate key value violates unique constraint/.test(error.message)) {
          throw new BadRequestException(error.detail);
        } else if (/violates foreign key constraint/.test(error.message)) {
          throw new BadRequestException(error.detail);
        } else {
          throw error;
        }
      } else {
        throw error;
      }
    }
  }
}

进而

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM