Aar*_*lal 6 javascript node.js typescript nestjs
在使用NestJS创建API时,我想知道哪种是处理错误/异常的最佳方法。我发现了两种不同的方法:
throw new Error(),有控制catch他们,不是抛出适当的那种HttpException(BadRequestException,ForbiddenException等..)HttpException。两种方法都各有利弊:
Error出于不同的原因返回,我如何从控制器中知道哪种对应的HttpException返回方式?Http在服务中包含相关内容似乎是错误的。我想知道,哪一种(如果有)是“嵌套js”的实现方式?
您如何处理此事?
Kim*_*ern 27
假设您的业务逻辑抛出 anEntityNotFoundError并且您想将其映射到 a 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;
}
}));
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过添加@UseInterceptors(NotFoundInterceptor)到控制器的类或方法中来使用它;甚至作为所有路由的全局拦截器。当然,您也可以在一个拦截器中映射多个错误。
在这个codeandbox 中尝试一下。
Ukp*_*chi 25
Nest Js提供了一个异常过滤器,可以处理应用程序层未处理的错误,因此我将其修改为返回500,即针对非Http异常的内部服务器错误。然后将异常记录到服务器,然后您就可以知道问题所在并修复它。
import 'dotenv/config';
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common';
@Catch()
export class HttpErrorFilter implements ExceptionFilter {
private readonly logger : Logger
constructor(){
this.logger = new Logger
}
catch(exception: Error, host: ArgumentsHost): any {
const ctx = host.switchToHttp();
const request = ctx.getRequest();
const response = ctx.getResponse();
const statusCode = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR
const message = exception instanceof HttpException ? exception.message || exception.message?.error: 'Internal server error'
const devErrorResponse: any = {
statusCode,
timestamp: new Date().toISOString(),
path: request.url,
method: request.method,
errorName: exception?.name,
message: exception?.message
};
const prodErrorResponse: any = {
statusCode,
message
};
this.logger.log( `request method: ${request.method} request url${request.url}`, JSON.stringify(devErrorResponse));
response.status(statusCode).json( process.env.NODE_ENV === 'development'? devErrorResponse: prodErrorResponse);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您可能不仅希望将服务绑定到 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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
进而