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

为何.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:27:03