【发布时间】:2023-02-19 20:56:56
【问题描述】:
目标:在响应完全处理并成功发送后运行一些代码。
根据文档,我尝试了这样的事情:
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log(`${Date.now()} Before...`);
const now = Date.now();
return next
.handle()
.pipe(tap(() => console.log(`${Date.now()} After... ${Date.now() - now}ms`)));
}
}
app 的配置如下:
const app = await NestFactory.create(AppModule, {
bufferLogs: true,
rawBody: true,
});
app.useGlobalInterceptors(new LoggingInterceptor());
app.useLogger(app.get(Logger));
然而,问题是"After..." 在"request completed" HTTP 日志之前记录(nestjs-pino 和pino-http)。我假设这意味着代码是在响应发出之前执行的。 (是对的吗?)
其他尝试
使用onFinished:
app.use((req: IncomingMessage, res: OutgoingMessage, next: any) => {
next();
onFinished(res, function (err, res) {
console.log(`${Date.now()} onFinished with req ${req.url}`);
console.log(`${Date.now()} onFinished with error ${err}`);
});
});
但结果是一样的。此外,除了错误处理的一些问题外,它还应用于每个 HTTP 请求,甚至是传出请求(这不是我想要的)。很可能这不是应该使用的方式。
我还发现了这个answer:
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const response = context.switchToHttp().getResponse();
response.on("close", () =>
console.log(`${Date.now()} After...`));
return next.handle();
}
}
这似乎有效,即它确实在 request completed 之后记录 After...。然而,作者发布了评论:也许不是一个好的选择.我是 NestJS 的新手,不确定为什么它不是一个好的选择。
发送响应后执行某些自定义代码的正确方法是什么?
谢谢。
【问题讨论】: