NestJS微服务异常处理

时间:2020-06-29 23:16:32

标签: microservices nestjs

我已经建立了一个看起来如下的微服务架构:

  • api-gateway(NestFactory.create(AppModule);
  • 服务1(NestFactory.createMicroservice<MicroserviceOptions>
  • 服务2(NestFactory.createMicroservice<MicroserviceOptions>) ...

服务如下:

service.controller.ts
service.handler.ts

handler就像典型的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中扔一个错误而不是拒绝它是行不通的

所以基本上,我有3个TryCatch块用于1个异常。 在我看来,这很冗长。

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

我们可以为Interceptor收到的回弹消息准备一个this.clientProxy.send并通过管道将其发送给客户端,以将错误响应发送给客户端,而无需明确捕获它两次。

1 个答案:

答案 0 :(得分:0)

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

我尽量避免使用.subscribereject(...)方法。 即使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);
}

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

@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(...)
        );
    }
}