NestJS Exception Filter无法捕获GraphQL验证异常如何解决?
在NestJS中捕获GraphQL验证异常并实现日志记录
你实现的CustomExceptionFilter无法捕获GraphQL验证异常(如必填字段缺失时抛出的BAD_INPUT或GRAPHQL_VALIDATION_FAILED),核心原因正如你猜测的:这类异常是在Apollo上下文层面抛出的,还未进入Nest的异常过滤器处理流程,因此常规的Nest异常过滤器无法拦截。
要捕获这类异常并完成日志记录,可通过Apollo Server的formatError配置项实现,该方法会拦截所有GraphQL执行阶段抛出的异常,包括验证类异常。
代码示例
方式1:直接在模块配置中处理
在AppModule的GraphQLModule配置里添加formatError逻辑:
import { Module, Logger } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; @Module({ imports: [ GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: true, formatError: (error) => { const logger = new Logger('GraphQLValidation'); // 匹配验证类异常并记录日志 if (error.extensions?.code === 'BAD_INPUT' || error.extensions?.code === 'GRAPHQL_VALIDATION_FAILED') { logger.error(`GraphQL验证异常: ${error.message}`, error.stack); } // 可根据需求返回自定义错误格式,或直接返回原错误 return error; }, }), ], }) export class AppModule {}
方式2:抽离为独立服务(更模块化)
先创建异常处理服务:
// graphql-error-handler.service.ts import { Injectable, Logger } from '@nestjs/common'; @Injectable() export class GraphQLErrorHandler { private readonly logger = new Logger(GraphQLErrorHandler.name); formatError(error: any) { const errorCode = error.extensions?.code; if (['BAD_INPUT', 'GRAPHQL_VALIDATION_FAILED'].includes(errorCode)) { this.logger.error(`验证失败: ${error.message}`, error.stack); } // 自定义返回格式示例(可选) return { message: error.message, code: errorCode, details: error.extensions?.exception?.response?.message || [], }; } }
再在模块中注入并使用:
// app.module.ts import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { GraphQLErrorHandler } from './graphql-error-handler.service'; @Module({ providers: [GraphQLErrorHandler], imports: [ GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, useFactory: (errorHandler: GraphQLErrorHandler) => ({ autoSchemaFile: true, formatError: errorHandler.formatError.bind(errorHandler), }), inject: [GraphQLErrorHandler], }), ], }) export class AppModule {}
原理说明
Apollo Server的formatError钩子会处理GraphQL执行全流程中抛出的异常,包括解析阶段的验证错误——这类错误不会经过Nest的异常过滤器管道,因此只能通过Apollo原生的钩子进行拦截和处理。
内容的提问来源于stack exchange,提问作者louzen
相关产品推荐
相关产品推荐

