ABP框架中如何在生产环境将未处理异常写入审计日志?
首先,你的猜测是对的——动作过滤器的执行顺序确实会导致它无法获取到完整的异常详情,具体原因如下:
在ASP.NET Core的过滤器执行流程中,异常过滤器(Exception Filter)会优先于动作过滤器的OnActionExecuted方法执行。当SendExceptionsDetailsToClients设置为false时,框架内置的异常处理逻辑(或你的自定义异常过滤器)会先捕获异常,将敏感的异常详情隐藏,再将处理后的结果返回。等动作过滤器的审计逻辑触发时,HttpContext中已经没有原始的异常详情了,自然无法记录。
针对这个问题,有几个可行的解决思路:
改用异常过滤器实现审计日志的异常捕获
直接实现IAsyncExceptionFilter或IExceptionFilter,在异常被处理前就捕获并记录完整的异常信息。这种方式能绕过动作过滤器的顺序限制,确保审计日志拿到最原始的异常详情,同时不影响生产环境隐藏异常返回给客户端的逻辑。自定义异常过滤器,提前传递异常信息给审计模块
如果必须保留动作过滤器的审计逻辑,可以在自定义异常过滤器中,先将异常详情保存到HttpContext的Items集合(或其他自定义存储)中,再执行异常隐藏逻辑。之后动作过滤器的审计代码就可以从这个存储中获取到原始异常信息,完成日志记录。检查审计日志的异常获取方式
有些审计模块会通过HttpContext.Features.Get<IExceptionHandlerFeature>()获取异常,但当SendExceptionsDetailsToClients为false时,这个Feature可能不会被框架填充。此时可以改为从ExceptionContext(在异常过滤器中)直接获取异常,再传递给审计模块。
内容的提问来源于stack exchange,提问作者Robert Chan

