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
相关产品推荐
相关产品推荐

