我想实现一个NestJS拦截器,该拦截器在命中请求处理程序之前创建并写入elasticSearch条目,并在处理程序完成后使用error / success-info更新该条目。为此,我正在使用:
@Injectable()
export class ElasticsearchInterceptor implements NestInterceptor {
constructor(private readonly elasticSearchService: ElasticsearchService) {}
async intercept(_context: ExecutionContext, next: CallHandler): Promise < Observable < any >> {
const elasticSearchPayload = new ElasticsearchPayloadBuilder()
.setOperation(...)
.build();
const elasticSearchEntry = await this.elasticSearchService.writeEntry(elasticSearchPayload);
return next
.handle()
.pipe(
catchError(err => {
elasticSearchPayload.status = err.status;
return throwError(err);
}),
tap(() => {
elasticSearchPayload.status = 'success';
}),
finalize(() => {
this.elasticSearchService.updateEntry(elasticSearchEntry.id, elasticSearchPayload));
}));
}
只要updateEntry
呼叫能够解决,就可以正常工作,但是如果失败,则会导致未处理的拒绝。我想确保错误已被捕获并抛出。我尝试使用{p>将updateEntry
承诺转换为新的Observable
finalize(() => {
return from(this.elasticSearchService.updateEntry(elasticSearchEntry.id, elasticSearchPayload))
.pipe(
catchError(err => throwError(err)));
}));
但这不能解决问题。如何防止未处理的拒绝并从updateEntry
返回错误?
答案 0 :(得分:1)
finalize
将在 teardown阶段中简单地调用提供的回调(例如,在complete
,来自源的error
或来自消费者的unsubscribe
之后) ,这就是为什么我认为这种方式不起作用。
话虽如此,这将是我的方法:
const main$ = return next
.handle()
.pipe(
catchError(err => {
elasticSearchPayload.status = err.status;
return throwError(err);
}),
tap(() => {
elasticSearchPayload.status = 'success';
}),
);
const elastic$ = from(this.elasticService/* ... */).pipe(
// might want to ignore elements and receive only errors
ignoreElements(),
catchError(err => throwError(err)),
);
return concat(main$, elastic$)