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

本文关键字:方法 是什么 记录 自定义异常 处理 | 更新日期: 2023-09-27 18:12:01

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

[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在记录它时为空!

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

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

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

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

在异常沿着调用堆栈向上传播时生成堆栈跟踪。在捕获异常的方法中抛出异常只会创建一个堆栈跟踪项。

您可以使用:

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

请注意,您可以简单地将这里的任何对象与人类可读的序列化格式(即格式化Json)结合使用。然后,您可以简单地记录对象的序列化表示,其中将保留所有公共字段/属性。

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

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

  1. 记录catch块中的异常
  2. 检查日志级别,只记录消息或完整异常信息。

例如,我们使用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);
}