NestJS interceptor中takeUntil触发request关闭后如何返回自定义状态码?
问题原因
你当前代码里的takeUntil操作符在监听到request的close事件时,只会静默终止上游可观察对象,不会抛出任何异常。NestJS 会认为请求已正常处理完成,自然返回默认的 200 状态码。
解决方法
你需要在close事件触发时主动抛出 HTTP 异常,NestJS 的内置异常过滤器会自动捕获该异常,返回你指定的自定义状态码。注意需要先判断响应头是否已经发送,避免出现重复设置响应的运行时错误。
修改后的代码参考:
import { fromEvent, Observable } from 'rxjs'; import { tap, mergeWith } from 'rxjs/operators'; import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException } from '@nestjs/common'; @Injectable() export class RequestCloseInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const request = context.switchToHttp().getRequest(); const response = context.switchToHttp().getResponse(); // 构造请求关闭事件流,触发时抛出自定义异常 const requestClose$ = fromEvent(request, 'close').pipe( tap(() => { // 仅在响应未发送时抛出异常,避免运行时报错 if (!response.headersSent) { // 此处可自定义状态码和响应信息,客户端主动关闭请求常用499状态码 throw new HttpException('Client closed request', 499); } }) ); return next.handle().pipe( mergeWith(requestClose$) ); } }
可选调整
如果你有特殊需求不需要走Nest全局异常过滤器的逻辑,也可以直接在事件回调里手动设置响应返回,写法如下:
intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const request = context.switchToHttp().getRequest(); const response = context.switchToHttp().getResponse(); fromEvent(request, 'close').subscribe(() => { if (!response.headersSent) { response.status(499).send({ code: 499, message: 'Client closed request' }); } }); return next.handle(); }
内容的提问来源于stack exchange,提问作者Zizhang Ai
相关产品推荐
相关产品推荐

