处理(记录)自定义异常的正确方法是什么?

时间:2011-10-21 08:16:24

标签: c# .net exception exception-handling

方法尝试记录自定义异常(自定义异常类作为代码示例)导致问题的情况:

[Serializable]
public class CustomException : Exception
{
    public CustomException() { }
    public CustomException(string message) : base(message) { }
    public CustomException(string message, Exception inner) : base(message, inner) { }
    protected CustomException(
      System.Runtime.Serialization.SerializationInfo info,
      System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { }
}

创建例外:

CustomException ex = new CustomException("Here is a new custom exception! ");
LogError(ex);

记录异常的方法(自定义和其他!):

public static void LogError(Exception ex)
{
    //Saving exception messages, inner exceptions etc
    //...
}

在这种情况下,自定义异常的ex.Stacktrace在记录时为n​​ull!

我认为原因是日志记录方法(试图成为通用方法)将Exception对象作为参数而不是CustomException(?)。创建日志记录方法的正确方法是什么,因为使用不同的异常类型重载它似乎有点违反直觉?

4 个答案:

答案 0 :(得分:2)

  

我认为原因是日志记录方法(尝试成为通用方法)将Exception对象作为参数而不是CustomException(?)

不正确的。它是null,因为你没有实际抛出异常,只是创建它。

堆栈跟踪是在异常通过callstack时生成的。在捕获异常的方法中抛出异常只会创建一个堆栈跟踪项。

答案 1 :(得分:1)

您可以使用:

public static void LogError<T>(T exception)
{
  // Serialize the exception here and write to log
}

请注意,您可以在此处使用任何对象与人类可读的序列化格式(即格式化的Json)进行组合。然后,您只需记录对象的序列化表示,其中将保留所有公共字段/属性。

请注意,您还需要为您构建stacktrace的throw / catch。

答案 2 :(得分:1)

在记录之前抛出CustomException实例。运行时将填写堆栈跟踪信息

答案 3 :(得分:1)

  1. 在catch块中记录异常
  2. 检查日志记录级别和仅记录消息或完整异常信息。
  3. 例如,我们使用TraceSource的扩展方法来记录异常:

    public static void TraceException(this TraceSource traceSource, Exception ex)
    {
        traceSource.TraceException(string.Empty, ex);
    }
    
    public static void TraceException(this TraceSource traceSource, string comment, Exception ex)
    {
        if (!string.IsNullOrWhiteSpace(comment))
            comment += "\r\n";
    
        traceSource.TraceEvent(TraceEventType.Error, (int)TraceEventType.Error,
                comment + "ExceptionType: {0} \r\n ExceptionMessage: {1}", ex.GetType(), ex.Message);
    
        if (traceSource.Switch.Level == SourceLevels.Verbose ||
            traceSource.Switch.Level == SourceLevels.All)
        {
            traceSource.TraceEvent(TraceEventType.Verbose, 0, ex.ToString());
        }
    }
    

    用法:

    catch(Exception ex)
    {
        _log.TraceException(ex);
    }