如何记录异常并重新引发为实际类型

本文关键字:新引发 类型 异常 何记录 记录 | 更新日期: 2023-09-27 17:56:12

我有一个查询处理程序装饰器,它记录任何异常:

public class QueryHandlerLogDecorator<TQuery, TResult> : IQueryHandler<TQuery, TResult>
    where TQuery : IQuery<TResult>
{
    private readonly IQueryHandler<TQuery, TResult> _handler;
    private readonly ILog _log;
    public QueryHandlerLogDecorator(IQueryHandler<TQuery, TResult> handler)
    {
       _handler = handler;
       _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    }
    public TResult Handle(TQuery query)
    {
        try
        {
             var result = _handler.Handle(query);
            _log.Info("Ok");
            return result;
        }
        catch (Exception ex)
        {
            _log.Error(ex.Message, ex);                
            throw new Exception(ex.Message);
        }
    }
}

虽然异常处理并不是世界上最糟糕的事情,但它意味着我失去了所抛出的异常的类型。

例如,如果我在应用程序中将ApplicationException扔得更低,则会将其捕获并重新抛出为Exception

如何重新引发被捕获为原始类型的异常?

如何记录异常并重新引发为实际类型

你可以

只使用throw;而不是throw new...或代替throw ex;

一旦抛出异常,它携带的部分信息是 堆栈跟踪。堆栈跟踪是方法调用层次结构的列表 从引发异常的方法开始,以 捕获异常的方法。如果异常被重新引发 在 throw 语句中指定异常,堆栈跟踪为 在当前方法和 之间的方法调用列表处重新启动 引发异常的原始方法和当前方法是 失去。要保留原始堆栈跟踪信息,但有例外, 使用 throw 语句而不指定异常。

更多在这里 : MSDN

仅使用 throw 关键字重新引发异常。这将重新引发传递给异常处理程序的异常。

public TResult Handle(TQuery query)
{
    try
    {
         var result = _handler.Handle(query);
        _log.Info("Ok");
        return result;
    }
    catch (Exception ex)
    {
        _log.Error(ex.Message, ex);                
        throw;
    }
}