为何.NET6接入GraphQL后自定义ErrorHandlerMiddleware未触发
问题原因
- HotChocolate GraphQL 框架默认内置了全局异常捕获逻辑,所有查询、突变执行阶段抛出的异常都会被内部拦截,按照 GraphQL 规范包装为
errors数组格式的响应返回,不会向上抛出到 ASP.NET Core 的中间件管道,因此你自定义的ErrorHandlerMiddleware无法捕获到这类异常。 - REST API 场景下没有框架层的异常拦截,因此异常可以正常回溯到中间件被捕获。
解决方案
推荐优先使用 HotChocolate 原生的错误过滤器适配你原有异常处理逻辑,既可以复用你已有的自定义异常判定规则,也能符合 GraphQL 标准响应规范。
步骤1:实现自定义错误过滤器
public class CustomGraphQLErrorFilter : IErrorFilter { public IError OnError(IError error) { // 无原生异常的错误直接返回 if (error.Exception == null) return error; return error.Exception switch { ApplicationBadRequestException e => error .WithMessage(e.Message) .WithCode("400") .Extension("metaData", e.metaData), ApplicationNotFoundException e => error .WithMessage(e.Message) .WithCode("404") .Extension("metaData", e.metaData), ApplicationUnAuthorizedException e => error .WithMessage("You are not authorized to perform this operation.") .WithCode("401"), _ => error .WithMessage("An error has occurred...Please try again later.") .Extension("exceptionMessage", GetExMessage(error.Exception)) .WithCode("500") }; } // 复用你原有异常信息提取逻辑 private string GetExMessage(Exception ex) { return ex.ToString(); } }
步骤2:注册错误过滤器
修改你的 Program.cs 中 GraphQL 服务注册代码,添加过滤器:
builder.Services.AddGraphQLServer() .AddQueryType<Query>() .AddMutationType<Mutation>() .AddProjections() .AddFiltering() .AddSorting() // 注册自定义错误过滤器 .AddErrorFilter<CustomGraphQLErrorFilter>();
可选:强制异常抛出到上层中间件(不推荐)
如果你不需要遵守 GraphQL 响应规范,一定要复用原有中间件逻辑,可以配置 HotChocolate 关闭内部异常捕获:
builder.Services.AddGraphQLServer() // 其他原有配置 .ModifyRequestOptions(opt => { opt.ExceptionHandling = ExceptionHandling.Throw; });
同时建议将你的错误中间件注册位置调整到管道最前面,确保能捕获所有后续链路的异常:
var app = builder.Build(); // 放在所有中间件最靠前的位置 app.UseMiddleware<ErrorHandlerMiddleware>(); // 后续其他中间件配置...
内容的提问来源于stack exchange,提问作者Mohamed Hasan
相关产品推荐
相关产品推荐

