我设置了一个如下所示的微服务架构:
- api 网关 (
NestFactory.create(AppModule);
) - 服务 1 (
NestFactory.createMicroservice<MicroserviceOptions>
) - 服务 2 (
NestFactory.createMicroservice<MicroserviceOptions>
) ...
服务看起来像这样:
service.controller.ts
service.handler.ts
在哪里handler
就像处理逻辑的典型 Monolith 中的服务。
目前,我正在通过以下方式捕获异常:
处理程序调用数据库但由于重复的 key (即电子邮件)而失败。
我捕获了这个异常并将其转换为
RpcException
在 ApiGateway 中,我捕获了
RpcException
像这样:return new Promise<Type>((resolve, reject) => { this.clientProxy .send<Type>('MessagePattern', { dto: DTO }) .subscribe(resolve, (err) => { logger.error(err); reject(err); }); });
我必须再次捕获被拒绝的 Promise 和
throw an HttpException
拥有ExceptionFilter
发送正确的错误响应。在 Promise 中抛出错误而不是拒绝它是行不通的)
所以基本上,我有 3 个 TryCatch block 用于 1 个异常。 这对我来说看起来非常冗长。
NestJS 微服务有没有更好的方法或最佳实践?
我们可以有一个Interceptor
吗? this.clientProxy.send
收到的反弹消息并将其通过管道发送给客户端发送错误响应而不显式捕获它 2 次?
最佳答案
不是您问题的完整答案,但聊胜于无。 :)
我尽量避免使用.subscribe
、reject(...)
方法。
即使 send
方法返回一个 Observable
,在大多数情况下您只希望得到 1 个响应。所以,在大多数情况下 .toPromise()
是有意义的。
一旦它成为一个 promise ,您就可以使用 async-await 语法,并且您没有回调,您可以有效地捕获所有异常(如果您愿意,可以重新抛出)。这有点帮助。
try {
const payload = { dto: DTO };
const response = await this.clientProxy.send<Type>('MessagePattern', payload).toPromise();
} catch (err) {
this.logger.error(err);
}
在服务器端,您可以有效地定义拦截器,它们几乎与用于 API Controller 的拦截器
相同。
@MessagePattern(messagePattern)
@UseInterceptors(CatchExceptionInterceptor)
public async someMethod(...) { }
您应该实现 NestInterceptor
接口(interface):
@Injectable()
export class CatchExceptionInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, stream$: Observable<any>): Observable<any> {
return stream$.pipe(
catchError(...)
);
}
}
关于microservices - NestJS 微服务异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62648027/