我已经建立了一个看起来如下的微服务架构:
NestFactory.create(AppModule);
)NestFactory.createMicroservice<MicroserviceOptions>
)NestFactory.createMicroservice<MicroserviceOptions>
)
... 服务如下:
service.controller.ts
service.handler.ts
handler
就像典型的Monolith中处理逻辑的服务。
目前,我正在通过以下方式捕获异常:
处理程序调用数据库,但由于密钥重复(即电子邮件)而失败。
我捕获了此异常并将其转换为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块用于1个异常。 在我看来,这很冗长。
关于NestJS微服务,是否有更好的方法或最佳实践?
我们可以为Interceptor
收到的回弹消息准备一个this.clientProxy.send
并通过管道将其发送给客户端,以将错误响应发送给客户端,而无需明确捕获它两次。
答案 0 :(得分:0)
不是您问题的完整答案,但是总比没有好。 :)
我尽量避免使用.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);
}
在服务器端,您可以有效地定义拦截器,这些拦截器几乎与用于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(...)
);
}
}