如何记录异常并重新抛出为实际类型

6 浏览
0 Comments

如何记录异常并重新抛出为实际类型

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

public class QueryHandlerLogDecorator : IQueryHandler
    where TQuery : IQuery
{
    private readonly IQueryHandler _handler;
    private readonly ILog _log;
    public QueryHandlerLogDecorator(IQueryHandler 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。

如何将捕获的异常重新抛出为原始类型?

0
0 Comments

问题的原因是在捕获异常后,使用throw关键字重新抛出异常时,无法保留原始异常的类型信息。这可能会导致在处理异常时丢失关键的调试信息。

解决方法是使用throw关键字时,将原始异常作为参数重新抛出。这样可以确保异常的类型信息得以保留,并能够提供准确的异常类型给异常处理程序。

在上述代码示例中,我们可以看到在捕获异常后,使用throw关键字将异常重新抛出。这样做可以确保异常的类型信息不被丢失。通过将原始异常作为参数传递给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 ex;
    }
}

通过将原始异常作为参数传递给throw关键字,我们可以确保异常的类型信息得以保留,并能够提供准确的异常类型给异常处理程序。这样可以帮助我们更好地定位和解决问题,并提供更好的调试信息。

0
0 Comments

在处理异常时,有时我们需要将异常记录下来并重新抛出,以便在之后的处理中能够准确地获取异常的信息和调用栈。然而,如果我们使用throw new...throw ex;来重新抛出异常,会导致原始的调用栈信息丢失。

解决这个问题的方法是使用throw;语句来重新抛出异常,而不指定具体的异常类型。这样做会保留原始的调用栈信息,使得在捕获该异常时能够准确地获取到异常的来源和调用路径。

具体来说,当我们使用throw;语句重新抛出异常时,异常的调用栈会重新从当前方法开始,并包含原始方法抛出异常的调用路径。这样做的好处是能够避免丢失原始调用栈信息,提供更准确的错误追踪。

如果我们想要了解更多关于该问题的信息,可以参考微软官方文档:MSDN

总结起来,当我们需要记录异常并重新抛出时,使用throw;语句而不指定具体的异常类型可以保留原始调用栈信息,提供更准确的错误追踪和处理。这是一种有效的异常处理方法,可以帮助我们更好地调试和修复代码中的问题。

0