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

后端 未结 2 1182
情歌与酒
情歌与酒 2021-02-07 01:30

While using NestJS to create API\'s I was wondering which is the best way to handle errors/exception. I have found two different approaches :

  1. Have individual servic
相关标签:
2条回答
  • 2021-02-07 02:19

    Let's assume your business logic throws an EntityNotFoundError and you want to map it to a NotFoundException.

    For that, you can create an Interceptor that transforms your errors:

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

    You can then use it by adding @UseInterceptors(NotFoundInterceptor) to your controller's class or methods; or even as a global interceptor for all routes. Of course, you can also map multiple errors in one interceptor.

    Try it out in this codesandbox.

    0 讨论(0)
  • 2021-02-07 02:19

    You may want to bind services not only to HTTP interface, but also for GraphQL or any other interface. So it is better to cast business-logic level exceptions from services to Http-level exceptions (BadRequestException, ForbiddenException) in controllers.

    In the simpliest way it could look like

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

    and then

    0 讨论(0)
提交回复
热议问题