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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:35:20