首页 > 解决方案 > NestJS 微服务异常处理

问题描述

我已经设置了一个如下所示的微服务架构:

服务看起来像这样:

service.controller.ts
service.handler.ts

Wherehandler就像处理逻辑的典型 Monolith 中的服务。

目前,我正在通过以下方式捕获异常:

  1. 处理程序调用数据库并由于重复键(即电子邮件)而失败。

  2. 我捕捉到这个异常并将其转换为RpcException

  3. 在 ApiGateway 中,我遇到了RpcException这样的情况:

        return new Promise<Type>((resolve, reject) => {
           this.clientProxy
            .send<Type>('MessagePattern', { dto: DTO })
            .subscribe(resolve, (err) => {
                logger.error(err);
                reject(err);
            });
        });
    
  4. 我必须再次捕获被拒绝的 Promise 并throw an HttpException发送ExceptionFilter正确的错误响应。在 Promise 中抛出错误而不是拒绝它是行不通的)

所以基本上,我有 1 个异常的 3 个 TryCatch 块。这对我来说看起来很冗长。

关于 NestJS 微服务,有没有更好的方法或最佳实践?

我们可以有一个Interceptor用于接收的反弹消息this.clientProxy.send并将其发送到客户端发送错误响应而不显式捕获 2 次吗?

标签: microservicesnestjs

解决方案


不是您问题的完整答案,但总比没有好。:)

我尽量避免使用.subscribe,reject(...)方法。尽管该send方法返回一个Observable,但在大多数情况下,您只希望得到 1 个响应。所以,在大多数情况下.toPromise()是有道理的。一旦它是一个承诺,您就可以使用 async-await 语法,并且您没有回调,您可以有效地捕获所有异常(如果您愿意,可以重新抛出)。它有点帮助。

try {
  const payload = { dto: DTO }; 
  const response = await this.clientProxy.send<Type>('MessagePattern', payload).toPromise();
} catch (err) {
  this.logger.error(err);
}

在服务器端,您可以有效地定义拦截器,它们几乎与Interceptors您用于 API 控制器的相同。

@MessagePattern(messagePattern)
@UseInterceptors(CatchExceptionInterceptor)
public async someMethod(...) { }

您应该实现NestInterceptor接口:

@Injectable()
export class CatchExceptionInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, stream$: Observable<any>): Observable<any> {
        return stream$.pipe(
            catchError(...)
        );
    }
}

推荐阅读