Nest
内置了一个异常层 ,负责处理应用程序中所有未处理的异常。
当应用程序代码未处理的异常时,该层会捕获该异常,并自动发送适当的、用户友好的响应。
此操作由内置的全局异常过滤器执行,该过滤器处理 HttpException
类型(及其子类)的异常。
当异常无法识别 (既不是 HttpException
也不是继承自 HttpException
类)时,内置异常过滤器会生成以下默认 JSON
响应:
json
{
"statusCode": 500,
"message": "Internal server error"
}
1.HttpException
Nest
中提供了 HttpException
类,该类是 Nest
中所有内置异常的基类。
HttpException
该类由 @nestjs/common
包暴露。
1-1.Throw HTTP exceptions
HttpException
类语法的使用形式如下:
new HttpException(message/JSON, status, options?)
其中,options
支持定义cause和 description
属性。
ts
@Get()
async findAll() {
try {
await this.service.findAll()
} catch (error) {
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: 'This is a custom message',
}, HttpStatus.FORBIDDEN, {
cause: error
});
}
}
1-2.Built-in HTTP exceptions
Nest
提供了一组继承自基类 HttpException
标准异常。
BadRequestException
UnauthorizedException
NotFoundException
ForbiddenException
NotAcceptableException
RequestTimeoutException
ConflictException
GoneException
HttpVersionNotSupportedException
PayloadTooLargeException
UnsupportedMediaTypeException
UnprocessableEntityException
InternalServerErrorException
NotImplementedException
ImATeapotException
MethodNotAllowedException
BadGatewayException
ServiceUnavailableException
GatewayTimeoutException
PreconditionFailedException
2.Custom exceptions
如果需要创建自定义异常,那么需要创建好异常层次结构,其中自定义异常继承自基类 HttpException
。
通过这种方法,Nest
将识别异常,并自动处理错误响应。
ts
export class ForbiddenException extends HttpException {
constructor() {
super('Forbidden', HttpStatus.FORBIDDEN);
}
}
然后可以直接这样使用它:
ts
@Get()
async findAll() {
throw new ForbiddenException();
}
3.Exception filters
基础(内置)异常过滤器可以自动处理许多情况,如果希望完全控制异常层,那么可以使用异常过滤器(控制精确的控制流以及发送回客户端的响应内容)。
例如,可以添加日志记录或根据某些动态因素使用不同的 JSON
模式:
ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
TIP
@Catch(HttpException)
装饰器将所需的元数据绑定到异常过滤器,告知 Nest
此特定过滤器只查找 HttpException
类型的异常。
@Catch()
装饰器可以接受单个参数,也可以接受逗号分隔的列表。