You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 14:24:06