Nest.js框架(2)

本文深入探讨了Nest.js框架中的错误处理,包括基础异常类、自定义异常、内置HTTP异常和异常过滤器的使用。此外,还介绍了如何创建和使用中间件,如应用中间件、函数式中间件以及全局中间件,展示了Nest.js强大的错误管理和中间件系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误处理

nest 内置的异常层负责处理整个应用程序中的所有抛出的异常。当捕获到未处理的异常时,最终用户将收到友好的响应。
 
开箱即用,此操作由内置的全局异常过滤器执行,该过滤器处理类型 HttpException (及其子类)的异常。每个发生的异常都
由全局异常过滤器处理 , 当这个异常无法被识别时 ( 既不是 HttpException 也不是继承的类 HttpException ) , 用户将
收到以下 JSON 响应 :
  {"statusCode": 500,"message": "Internal server error"}
 
同时,我们也可以根据需要进行异常处理
 
 

基础异常类

Nest提供了一个内置的 HttpException 类,它从 @nestjs/common 包中导入。

现在当客户端调用这个端点时,响应如下所示:
  { "statusCode": 403, "message": "Forbidden" }
 
HttpException 构造函数有两个必要的参数来决定响应 :
 
response 参数定义 JSON 响应体。它可以是 string object ,如下所述。
 
status 参数定义 HTTP 状态代码。
 
默认情况下, JSON 响应主体包含两个属性:
 
statusCode :默认为
status 参数中提供的 HTTP 状态代码
 
message: 基于状态的
HTTP 错误的简短描述
 
仅覆盖 JSON 响应主体的消息部分,请在 response 参数中提供一个 string
 
要覆盖整个 JSON 响应主体,请在 response 参数中传递一个 object Nest 将序列化对象,并将其作为 JSON 响应返回。
 
第二个构造函数参数 -status- 是有效的 HTTP 状态代码
 
 
使用上面的代码,响应如下所示:
 
 

自定义异常

如果确实需要创建自定义的异常,则最好创建自己的异常层次结构,其中自定义异常从基 HttpException 类继承。 使用这种方法, Nest 可以识别我
们定义的异常,并自动处理错误响应。
由于 ForbiddenException 扩展了基础 HttpException ,它将和核心异常处理程序一起工作,因此我们可以在 findAll() 方法中使用它。
 
 
在许多情况下,我们无需编写自定义异常,而可以使用内置的 Nest HTTP 异常
 

内置HTTP异常

为了减少样板代码, Nest 提供了一系列继承自核心异常 HttpException 的可用异常,所有这些都可以在 @nestjs/common 包中找到:
 
BadRequestException
请求错误
 
UnauthorizedException
未授权
 
NotFoundException
请求路径未找到
 
ForbiddenException
用户无权限访问该资源,请求失败
 
NotAcceptableException
 
RequestTimeoutException
请求超时
 
ConflictException
 
GoneException
 
PayloadTooLargeException
 
UnsupportedMediaTypeException
 
UnprocessableException
请求被服务器正确解析,但是包含无效字段
 
InternalServerErrorException
服务器发生错误
 
NotImplementedException
服务没有实现请求方式
 
BadGatewayException
 
ServiceUnavailableException
 
GatewayTimeoutException

 

异常过滤器

虽然基本(内置)异常过滤器可以为您自动处理许多情况,但有时您可能希望对异常层拥有完全控制权,例如,您可能要添加日志记录或基于一
些动态因素使用其他 JSON 模式。 异常过滤器正是为此目的而设计的。 它们使您可以控制精确的控制流以及将响应的内容发送回客户端。
 
创建一个异常过滤器,它负责捕获作为 HttpException 类实例的异常,并为它们设置自定义响应逻辑。为此,我们需要访问底层平台 Request
Response 。我们将访问 Request 对象,以便提取原始 url 并将其包含在日志信息中。我们将使用 Response.json() 方法,使用 Response 对象直接控制发
送的响应。
 
所有异常过滤器都应该实现通用的 ExceptionFilter<T> 接口。它需要你使用有效签名提供 catch(exception: T, host: ArgumentsHost) 方法。 T 表示异常的
类型。
 
 
@Catch() 装饰器绑定所需的元数据到异常过滤器上。它告诉 Nest 这个特定的过滤器正在寻找 HttpException 而不是其他的。在实践中,
@Catch() 可以传递多个参数,所以你可以通过逗号分隔来为多个类型的异常设置过滤器
 
让我们将 HttpExceptionFilter 绑定到 CatsController create() 方法上。
 
在这里使用了 @UseFilters() 装饰器。和 @Catch() 装饰器类似,它可以使用单个过滤器实例,也可以使用逗号分隔的过滤器实例列表。 我们
创建了 HttpExceptionFilter 的实例。另一种可用的方式是传递类(不是实例),让框架承担实例化责任并启用依赖注入。
 
尽可能使用类而不是实例。由于 Nest 可以轻松地在整个模块中重复使用同一类的实例,因此可以减少内存使用。
 
在上面的示例中, HttpExceptionFilter 仅应用于单个 create() 路由处理程序,使其成为方法范围的。 异常过滤器的作用域可以划分为不同的
级别:方法范围,控制器范围或全局范围。
要创建一个全局范围的过滤器,您需要执行以下操作

捕获异常

为了捕获每一个未处理的异常(不管异常类型如何),将 @Catch() 装饰器的参数列表设为空,例如 @Catch()

要创建一个全局范围的过滤器,您需要执行以下操作
 

Providers(提供者)

Providers Nest 的一个基本概念。许多基本的 Nest 类可能被视为 provider - service, repository, factory, helper 等等。 他们都可以通过
constructor 注入依赖关系。 这意味着对象可以彼此创建各种关系,并且 连接 对象实例的功能在很大程度上可以委托给 Nest 运行时系统。
Provider 只是一个用 @Injectable() 装饰器注释的类。
 
控制器应处理 HTTP 请求并将更复杂的任务委托给 providers Providers 是纯粹的 JavaScript 类,在其类声明之前带有 @Injectable() 装饰器。
 

创建服务

要使用 CLI 创建服务类,只需执行 $ nest g service cats 命令
 

依赖注入

contrlloer 使用我们创建的服务,我们采用是通过类的控制器构造函数进行依赖注入的。
 
Nest 是建立在强大的设计模式 , 通常称为依赖注入。
 
Nest 中,借助 TypeScript 功能,管理依赖项非常容易,因为它们仅按类型进行解析

 

模块

模块是具有 @Module() 装饰器的类。 @Module() 装饰器提供了元数据, Nest 用它来组织应用程序结构。
 
每个 Nest 应用程序至少有一个模块,即根模块。根模块是 Nest 开始安排应用程序树的地方。事实上,根模块可能是应用程序中唯一的模块,
特别是当应用程序很小时,但是对于大型程序来说这是没有意义的。在大多数情况下,您将拥有多个模块,每个模块都有一组紧密相关的
功能。
 
@module() 装饰器接受一个描述模块属性的对象:
 
providers Nest 注入器实例化的提供者,并且可以至少在整个模块中共享
 
controllers 必须创建的一组控制器
 
imports
导入模块的列表,这些模块导出了此模块中所需提供者
 
exports
由本模块提供并应在其他模块中可用的提供者的子集。
 
 

中间件

中间件是在路由处理程序 之前 调用的函数。 中间件函数可以访问请求和响应对象,以及应用程序请求响应周期中的 next() 中间件函数。
next() 中间件函数通常由名为 next 的变量表示。
 
Nest 中间件实际上等价于 express 中间件
 
中间件函数可以执行以下任务 :
 
执行任何代码
 
对请求和响应对象进行更改
 
结束请求 - 响应周期
 
调用堆栈中的下一个中间件函数
 
如果当前的中间件函数没有结束请求 - 响应周期 , 它必须调用 next() 将控制传递给下一个中间件函数。否则 , 请求将被挂起。
 
 

创建中间件

可以在函数中或在具有 @Injectable() 装饰器的类中实现自定义 Nest 中间件。 这个类应该实现 NestMiddleware 接口 , 而函数
没有任何特殊的要求。
 
 
Nest 中间件完全支持依赖注入。 就像提供者和控制器一样,它们能够注入属于同一模块的依赖项(通过 constructor )。
 

应用中间件

中间件不能在 @Module() 装饰器中列出。我们必须使用模块类的 configure() 方法来设置它们。包含中间件的模块必须实现
NestModule 接口
 
我们还可以在配置中间件限制处理的路径和方法,只需要将路径和方法传递给 forRoutes() 方法,也可以可以使用
async/await 来实现

函数式中间件

我们使用的 LoggerMiddleware 类非常简单。它没有成员,没有额外的方法,没有依赖关系。为什么我们不能只使用一个简
单的函数?这是一个很好的问题,因为事实上 - 我们可以做到。这种类型的中间件称为函数式中间件。让我们把 logger
换成函数。
.
当您的中间件没有任何依赖关系时,我们可以考虑使用函数式中间件。
 

连续中间件

为了绑定顺序执行的多个中间件,我们可以在 apply() 方法内用逗号分隔它们

全局中间件

如果我们想一次性将中间件绑定到每个注册路由,我们可以使用由INestApplication实例提供的 use()方法:

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值