首页 > 其他分享 >【踩坑】.NET 8.0 自定义IExceptionHandler不生效

【踩坑】.NET 8.0 自定义IExceptionHandler不生效

时间:2024-06-18 17:34:41浏览次数:25  
标签:8.0 自定义 IExceptionHandler Response public context NET logger StatusCode

中间件实现异常处理

在ASP.NET Core里,我们可以使用中间件(Middleware)实现全局的异常处理。 如内置的异常处理中间件 UseExceptionHandler

app.UseExceptionHandler(appError =>
        {
            appError.Run(async context =>
            {
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.ContentType = "application/json";
                var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                if (contextFeature != null)
                {
                    logger.LogError($"Something went wrong: {contextFeature.Error}");
                    await context.Response.WriteAsync(new ErrorDetails()
                    {
                        StatusCode = context.Response.StatusCode,
                        Message = "Internal Server Error."
                    }.ToString());
                }
            });
        });

或者如下干脆完全自定义一个中间件

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILoggerManager _logger;
    public ExceptionMiddleware(RequestDelegate next, ILoggerManager logger)
    {
        _logger = logger;
        _next = next;
    }
    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
        }
        catch (Exception ex)
        {
            _logger.LogError($"Something went wrong: {ex}");
            await HandleExceptionAsync(httpContext, ex);
        }
    }
    private async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        await context.Response.WriteAsync(new ErrorDetails()
        {
            StatusCode = context.Response.StatusCode,
            Message = "Internal Server Error from the custom middleware."
        }.ToString());
    }
}

当然还可以使用过滤器(Filter)来实现,即IExceptionFilter, 这些都能很方便实现自定义的全局异常处理。

IExceptionHandler 实现异常处理

在.NET 8.0里,微软新引入的IExceptionHandler也可以实现同样的功能,看官方的异常处理文档IExceptionHandler似乎已经是最推荐的异常处理方法。
在微软新开的项目里,IExceptionHandler正被广泛使用,比如Semantic Kernel
image
下面是官方文档给的一个简单实现

using Microsoft.AspNetCore.Diagnostics;

namespace ErrorHandlingSample
{
    public class CustomExceptionHandler : IExceptionHandler
    {
        private readonly ILogger<CustomExceptionHandler> logger;
        public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
        {
            this.logger = logger;
        }
        public ValueTask<bool> TryHandleAsync(
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken)
        {
            var exceptionMessage = exception.Message;
            logger.LogError(
                "Error Message: {exceptionMessage}, Time of occurrence {time}",
                exceptionMessage, DateTime.UtcNow);
            // Return false to continue with the default behavior
            // - or - return true to signal that this exception is handled
            return ValueTask.FromResult(false);
        }
    }
}

使用也很简单

builder.Services.AddExceptionHandler<CustomExceptionHandler>();

然而,如果你按照文档实现完之后,你所期待的自定义异常处理并不会生效,你必须添加一个空的lambda给UseExceptionHandlerAddExceptionHandler才会生效:)

app.UseExceptionHandler(o => { });

为什么会这样?看这个https://github.com/dotnet/aspnetcore/issues/51888, 去年下半年就有人发现了,微软尝试修复https://github.com/dotnet/aspnetcore/pull/51898, 但是改动有breaking change给拒绝了,加上有上面提到的workaround,就一直搁置了。
image
虽然又不是不能用,但是看着难受,开头就介绍了,UseExceptionHandler是启用内置的异常处理中间件的方法,而AddExceptionHandler是用来注册.NET 8.0新引入的IExceptionHandler,这个workaround有点一言难尽,欢迎踊跃提交PR去fix,先到先得☺

标签:8.0,自定义,IExceptionHandler,Response,public,context,NET,logger,StatusCode
From: https://www.cnblogs.com/netry/p/18254779/dot-net-iexceptionhandler-not-working

相关文章

  • NetCore资料
    .NET项目中NLog的配置与使用     NETCore中的验证组件FluentValidation  Core数据校验:FluentValidation用法.NETCore学习资料精选:入门   教程:ASP.NETCore入门  C#/.NET/.NETCore推荐学习书籍  如何学习CORE  .netcore中使用Autofac    Autofa......
  • 【New Relic】给基于.NET Framework 4.0 的 exe 程序安装New Relic
    由于.NETFramework4.0是比较古老的版本,只有NewRelic7.0以下的版本才会支持.NETFramework4.0的引用程序。 Technicalsupportfor.NETFramework4.0orlower 你可以参考这个官方InstallNewRelictoMonitoryourApp的文档。 1.创建NewRelic账号创建一个Ne......
  • k8s的python客户端库--kubernetes
    简介Kubernetes是什么Kubernetes是一个全新的基于容器技术的分布式架构解决方案,是Google开源的一个容器集群管理系统,Kubernetes简称K8S。Kubernetes是一个一站式的完备的分布式系统开发和支撑平台,更是一个开放平台,对现有的编程语言、编程框架、中间件没有任何侵入性。K......
  • Net6 EFCore 基于MSSQL & T4 自动生成字段注释
    文件模板代码<#@templatelanguage="C#"#><#@outputextension=".cs"#><#@assemblyname="System.Core"#><#@importnamespace="System.IO"#><#@importnamespace="System.Linq"#>......
  • Qt 应用程序中自定义鼠标光标
    在Qt应用程序中,你可以自定义鼠标光标。你可以使用`QCursor`类来设置不同类型的鼠标光标,比如内置样式或者自定义的图片。以下是一些使用示例:使用内置光标样式Qt提供了一些内置的光标样式,你可以使用这些样式来改变光标的外观,例如箭头、手形、等待图标等等。1#include<QA......
  • 使用.NET Core创建Windows服务
    一、使用VS创建打开VisualStudio,创建新项目,找到WorkerService模板。 二、项目结构说明创建出来的项目,包含两个主要文件:1)其中Program.cs文件是应用的启动“引导程序”;2)另外一个文件是worker.cs文件,在这个文件中,可以编写自己的服务逻辑。 三、将应用转换成Window服务......
  • 记一次 .NET某机械臂上位系统 卡死分析
    一:背景1.讲故事前些天有位朋友找到我,说他们的程序会偶发性的卡死一段时间,然后又好了,让我帮忙看下怎么回事?窗体类的程序解决起来相对来说比较简单,让朋友用procdump自动抓一个卡死时的dump,拿到dump之后,上windbg说话。二:WinDbg分析1.主线程在做什么要想看主线程在做什么,很......
  • 20、docker-自定义网络
    查看所有的docker网络 网络模式:·bridge桥接(docker默认、自己定义也使用桥接模式)·none  不配置网络·host和宿主机共享网络·container容器网络连通(用的少) ================================================================......
  • LiveCharts2:简单灵活交互式且功能强大的.NET图表库
    前言之前的文章中提到过ScottPlot、与oxyplot,这两个是比较常用的.NET图表库,今天介绍一款新的.NET图表库:LiveCharts2。LiveCharts2介绍LiveCharts2是一个现代化的数据可视化库,用于创建动态和交互式图表,支持.NET平台。它是LiveCharts的进化版,旨在提供更高性能、更灵活和更易......
  • ADO.NET 事务操作封装
    ///<summary>///事务处理///</summary>///<paramname="sqlList">sql语句数组</param>///<returns></returns>///<exceptioncref="Exception"></exception>publicstaticboolOpenTransation(List......