代码之家  ›  专栏  ›  技术社区  ›  Aaron Ullal

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

  •  3
  • Aaron Ullal  · 技术社区  · 6 年前

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

    1. 有独立的服务和验证管道 throw new Error() ,让控制器 catch 然后再把合适的 HttpException ( BadRequestException ,请 ForbiddenException 等)
    2. 让控制器简单地调用负责处理该业务逻辑部分的服务/验证管道方法,并抛出适当的 HttpException异常 是的。

    两种方法各有利弊:

    1. 这似乎是正确的方法,但是,服务可以返回 Error 出于不同的原因,我如何从控制器中知道 HttpException异常 回来?
    2. 非常灵活,但有 Http 服务业相关的东西似乎是错的。

    我在想,哪一种(如果有的话)是“nest js”的方式?

    你怎么处理这件事?

    2 回复  |  直到 5 年前
        1
  •  2
  •   Kim Kern    5 年前

    假设您的业务逻辑抛出 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) 到控制器的类或方法;甚至作为所有路由的全局拦截器。当然,您也可以在一个拦截器中映射多个错误。

    试试这个 codesandbox 是的。

        2
  •  1
  •   Alexey Petushkov    6 年前

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

    以最简单的方式

    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;
          }
        }
      }
    }
    

    然后