关于c#:如何记录异常并重新抛出实际类型


How to log an exception and rethrow as the actual type

本问题已经有最佳答案,请猛点这里访问。

我有一个查询处理程序decorator,它记录所有异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;

Once an exception is thrown, part of the information it carries is the
stack trace. The stack trace is a list of the method call hierarchy
that starts with the method that throws the exception and ends with
the method that catches the exception. If an exception is re-thrown by
specifying the exception in the throw statement, the stack trace is
restarted at the current method and the list of method calls between
the original method that threw the exception and the current method is
lost. To keep the original stack trace information with the exception,
use the throw statement without specifying the exception.

这里有更多:msdn


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
    }
}