如何在Elmah.axd中显示自定义异常类型与消息并保留原始堆栈跟踪?
解决Elmah显示自定义异常类型和消息但保留原始堆栈的问题
问题背景
我需要在elmah.axd的表格中显示自定义异常MyCustomException的类型和自定义错误消息,同时保留被包装的子异常(比如IndexOutOfRangeException)的原始堆栈跟踪。但目前调用ErrorSignal.FromCurrentContext().Raise(cex)时,Elmah仍显示子异常的类型与消息,而非自定义异常的信息。
原因分析
Elmah的默认逻辑是递归遍历异常链,优先展示最内层的原始异常,目的是突出问题的根源。所以当你传入带有InnerException的自定义异常时,Elmah会自动“穿透”到内部异常,导致表格里显示的是内部异常的类型和消息。
解决方案
方案1:手动构建Error对象(局部生效)
不要直接把自定义异常传给Raise方法,而是手动创建Error实例,覆盖显示用的Type和Message,同时保留完整的异常链和堆栈信息。
示例代码:
catch(MyCustomException cex){ // 基于自定义异常创建Error对象 var error = new Error(cex); // 强制指定显示的类型和消息为自定义异常的内容 error.Type = nameof(MyCustomException); error.Message = cex.Message; // 提交到Elmah ErrorSignal.FromCurrentContext().Raise(error); }
方案2:全局错误过滤器(全局生效)
实现IErrorFilter接口,在错误被记录前自动修改显示信息,不需要每次手动处理。
首先定义过滤器类:
public class CustomExceptionFilter : IErrorFilter { public void OnErrorModuleFiltering(object sender, ExceptionFilterEventArgs args) { var customEx = args.Exception as MyCustomException; if (customEx == null) return; // 构建自定义的Error对象 var error = new Error(customEx); error.Type = nameof(MyCustomException); error.Message = customEx.Message; // 取消原有的错误处理,改用我们自定义的Error对象 args.Dismiss(); ErrorSignal.FromCurrentContext().Raise(error); } }
然后在Web.config中注册这个过滤器(ASP.NET传统项目):
<elmah> <errorFilter> <test> <!-- 匹配你的自定义异常全限定名 --> <equal binding="Exception.Type" value="YourNamespace.MyCustomException" /> <filter type="YourNamespace.CustomExceptionFilter, YourAssemblyName" /> </test> </errorFilter> </elmah>
效果说明
两种方案都能让elmah.axd表格显示自定义异常的类型和消息,同时在错误详情页面依然能看到完整的异常链(包括内部异常的堆栈跟踪),完全符合需求。
内容的提问来源于stack exchange,提问作者sTx
相关产品推荐
相关产品推荐

