Skip to content

异常过滤器

HTTP 异常过滤器层与相应的微服务层之间唯一的区别是,你应该使用 RpcException 而不是抛出 HttpException

typescript
throw new RpcException('Invalid credentials.');

提示

RpcException 类从 @nestjs/microservices 包中导入。

通过上面的示例,Nest 将处理抛出的异常并返回具有以下结构的 error 对象:

json
{
  "status": "error",
  "message": "Invalid credentials."
}

过滤器

微服务异常过滤器的行为与 HTTP 异常过滤器类似,只有一个小区别:catch() 方法必须返回一个 Observable

typescript
// rpc-exception.filter
import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}

警告

使用混合应用时,全局微服务异常过滤器默认不会启用。

以下示例使用了手动实例化的方法作用域过滤器。与基于 HTTP 的应用程序一样,你也可以使用控制器作用域的过滤器(即在控制器类前加上 @UseFilters() 装饰器)。

typescript
@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}

继承

通常,你会创建完全自定义的异常过滤器来满足应用程序的需求。然而,在某些情况下,你可能只想简单地扩展核心异常过滤器,并根据特定因素覆盖其行为。

要将异常处理委托给基础过滤器,你需要扩展 BaseExceptionFilter 并调用继承的 catch() 方法。

typescript
import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}

上面的实现只是一个展示方法的外壳。你的扩展异常过滤器实现应该包含你定制的业务逻辑(例如,处理各种条件)。

基于 NestJS 官方文档翻译