[英]What is the nestjs error handling approach (business logic error vs. http error)?
While using NestJS to create API's I was wondering which is the best way to handle errors/exception.在使用 NestJS 创建 API 时,我想知道哪种是处理错误/异常的最佳方式。 I have found two different approaches :
我发现了两种不同的方法:
throw new Error()
, have the controller catch
them and then throw the appropriate kind of HttpException
( BadRequestException
, ForbiddenException
etc..)throw new Error()
,让控制器catch
它们,然后抛出适当类型的HttpException
( BadRequestException
、 ForbiddenException
等。)HttpException
.HttpException
。 There are pros and cons to both approaches:这两种方法各有利弊:
Error
for different reasons, how do I know from the controller which would be the corresponding kind of HttpException
to return?Error
,我如何从控制器知道哪个是相应类型的HttpException
返回?Http
related stuff in services just seems wrong.Http
相关的东西似乎是错误的。 I was wondering, which one (if any) is the "nest js" way of doing it?我想知道,哪一种(如果有的话)是“嵌套 js”的做法?
How do you handle this matter?你怎么处理这件事?
Let's assume your business logic throws an EntityNotFoundError
and you want to map it to a NotFoundException
.假设您的业务逻辑抛出
EntityNotFoundError
并且您希望将其映射到NotFoundException
。
For that, you can create an Interceptor
that transforms your errors:为此,您可以创建一个
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;
}
}));
}
}
You can then use it by adding @UseInterceptors(NotFoundInterceptor)
to your controller's class or methods;然后,您可以通过将
@UseInterceptors(NotFoundInterceptor)
添加到控制器的类或方法中来使用它; 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 .在这个codeandbox 中尝试一下。
You may want to bind services not only to HTTP interface, but also for GraphQL or any other interface.您可能不仅希望将服务绑定到 HTTP 接口,还希望绑定到 GraphQL 或任何其他接口。 So it is better to cast business-logic level exceptions from services to Http-level exceptions (BadRequestException, ForbiddenException) in controllers.
因此最好将业务逻辑级别的异常从服务转换为控制器中的 Http 级别异常(BadRequestException、ForbiddenException)。
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进而
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.