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

NestJS中AllExceptionFilter触发异常后服务无法接收请求如何解决?

NestJS全局异常过滤器导致服务无法接收请求的问题解决

问题描述

使用NestJS并创建了AllExceptionFilter全局异常过滤器后,通过httpService发起POST请求返回错误时,NestJS便无法再接收RESTful API请求。

错误日志

/Users/username/Documents/workspace/project/nestjs/src/shared/filters/custom-exception.filter.ts:29
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
                        ^
TypeError: Cannot read properties of undefined (reading 'getRequestUrl')
    at AllExceptionsFilter.catch (/Users/username/Documents/workspace/project/nestjs/src/shared/filters/custom-exception.filter.ts:29:25)
    at ExceptionsHandler.invokeCustomFilters (/Users/username/Documents/workspace/project/nestjs/node_modules/@nestjs/core/exceptions/exceptions-handler.js:33:26)
    at ExceptionsHandler.next (/Users/username/Documents/workspace/project/nestjs/node_modules/@nestjs/core/exceptions/exceptions-handler.js:13:18)
    at /Users/username/Documents/workspace/project/nestjs/node_modules/@nestjs/core/router/router-proxy.js:13:35
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

相关代码

未添加try/catch的httpService调用代码

await firstValueFrom(this.httpService.post(
      url,
      {
        id: 'id'
      },
    ));

AllExceptionFilter代码

import {
    ExceptionFilter,
    Catch,
    ArgumentsHost,
    HttpException,
    HttpStatus,
  } from '@nestjs/common';
  import { HttpAdapterHost } from '@nestjs/core';
  
  @Catch()
  export class AllExceptionsFilter implements ExceptionFilter {
    constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
  
    catch(exception: unknown, host: ArgumentsHost): void {
      // In certain situations `httpAdapter` might not be available in the
      // constructor method, thus we should resolve it here.
      const { httpAdapter } = this.httpAdapterHost;
  
      const ctx = host.switchToHttp();
  
      const httpStatus =
        exception instanceof HttpException
          ? exception.getStatus()
          : HttpStatus.INTERNAL_SERVER_ERROR;
  
      const responseBody = {
        statusCode: httpStatus,
        timestamp: new Date().toISOString(),
        path: httpAdapter.getRequestUrl(ctx.getRequest()),
      };
  
      httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
    }
  }

解决方案

方案1:修复全局异常过滤器,兼容非HTTP上下文

修改AllExceptionsFilter的catch方法,增加对HTTP上下文的有效性判断,避免在非HTTP环境下执行HTTP相关操作:

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    const { httpAdapter } = this.httpAdapterHost;

    // 检查httpAdapter是否可用
    if (!httpAdapter) {
      throw exception;
    }

    // 尝试切换到HTTP上下文
    const ctx = host.switchToHttp();
    const request = ctx.getRequest();
    const response = ctx.getResponse();

    // 验证是否为有效的HTTP请求上下文
    if (!request || !response) {
      // 非HTTP上下文,直接抛出异常交由对应处理器处理
      throw exception;
    }

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(request),
    };

    httpAdapter.reply(response, responseBody, httpStatus);
  }
}

方案2:在httpService调用处主动捕获异常

在发起外部请求时主动捕获异常,避免异常冒泡到全局过滤器引发服务异常:

import { HttpException, HttpStatus } from '@nestjs/common';
import { firstValueFrom } from 'rxjs';

// ...
try {
  await firstValueFrom(this.httpService.post(
    url,
    { id: 'id' },
  ));
} catch (error) {
  // 可根据实际需求处理错误,比如记录日志或抛出标准化业务异常
  throw new HttpException('外部服务请求失败', HttpStatus.BAD_GATEWAY);
}

原因分析

当httpService的请求失败抛出异常且未被捕获时,异常会被全局过滤器处理。此时若当前执行上下文并非HTTP请求上下文(或HTTP上下文已失效),ctx.getRequest()会返回undefined,同时httpAdapter可能无法正常获取,导致过滤器内部抛出未处理的类型错误,最终使NestJS服务无法继续接收新的请求。

内容的提问来源于stack exchange,提问作者tuioku

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:05:21