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

NestJS中Prisma异常过滤器在Cron任务中失效问题求助

NestJS Prisma异常过滤器在Cron任务中失效的解决方案

核心原因

你的异常过滤器仅适配HTTP上下文,硬编码调用host.switchToHttp()获取请求和响应对象,但Cron任务不属于HTTP上下文,导致无法获取对应对象,异常处理逻辑失败,最终程序直接抛出PrismaClientKnownRequestError并终止。

修复方案

1. 修改过滤器以支持多上下文

修改过滤器代码,增加上下文类型判断,分别处理HTTP和非HTTP(如Cron)场景:

import { Catch, ArgumentsHost, HttpStatus, Logger, ContextType } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { Prisma } from '@prisma/client';
import { Request, Response } from 'express';

@Catch(Prisma.PrismaClientKnownRequestError)
export class PrismaClientKnownRequestErrorExceptionFilter extends BaseExceptionFilter {
  logger = new Logger('PrismaClient');

  catch(
    exception: Prisma.PrismaClientKnownRequestError,
    host: ArgumentsHost,
  ): void {
    const contextType: ContextType = host.getType();
    
    let statusCode: HttpStatus;
    let message: string;
    switch (exception.code) {
      case 'P2002': // 唯一约束冲突
        statusCode = HttpStatus.CONFLICT;
        message = `唯一约束失败,约束字段:${exception?.meta?.['target']}`;
        break;
      // 补充其他Prisma错误码的处理逻辑
      default:
        statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
        message = exception.message.replace(/\r/g, '').replace(/\n/g, '');
        break;
    }

    this.logger.error(message);

    // 根据上下文类型处理
    if (contextType === 'http') {
      const ctx = host.switchToHttp();
      const request = ctx.getRequest<Request>();
      const response = ctx.getResponse<Response>();
      this.handleHttpResponse(statusCode, message, request, response);
    } else {
      // Cron等非HTTP场景:仅记录日志,无需返回HTTP响应
      this.logger.warn(`非HTTP上下文捕获Prisma错误:${message}`);
      // 如需自定义Cron错误逻辑(如重试、告警)可在此添加
    }
  }

  handleHttpResponse(
    statusCode: HttpStatus,
    message: string,
    request: Request,
    response: Response,
  ) {
    response.status(statusCode).json({
      statusCode,
      message,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  }
}

2. 关键修改说明

  • 上下文判断:通过host.getType()识别当前执行环境是HTTP还是非HTTP(Cron属于此类)
  • 移除HTTP依赖:不再强制获取HTTP请求/响应对象,避免Cron场景下的未定义错误
  • 分场景处理:HTTP场景保持原有响应逻辑,Cron场景仅记录日志,确保程序不会崩溃

3. 配置验证

你在App模块中注册APP_FILTER的方式是正确的,全局过滤器会覆盖所有上下文,只要过滤器支持多上下文处理,就能正常工作。

额外提示

  • 若Cron任务需要特定错误处理(如自动重试、发送告警),可在非HTTP分支中添加对应逻辑
  • 确保@nestjs/schedule已正确安装并配置,Cron任务能正常触发

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:45:34