检查是否在更高级别处理异常

时间:2013-02-04 22:49:19

标签: c# .net exception exception-handling

有没有办法检查是否在更高的应用程序级别处理异常以跳过日志记录并重新抛出?像这样,例如:

        try
        {
            // Execute some code
        }
        catch (Exception e)
        {
            if(!ExceptionIsHandled())
                LogError(e);
            throw e;
        }

4 个答案:

答案 0 :(得分:1)

我没有意识到什么。如果您致力于此设计(请参阅结尾处的注释),那么可以为异常编写一个包装器HandledException,并使其InnerException成为一个被扔了。然后你可以让你的代码看起来像:

    try
    {
        // Execute some code
    }
    catch (HandledException e)
    {
        LogError(e.InnerException);
        // Do something else
    }
    catch (Exception e)
    {
        throw ;
    }

以下是陈规定型的Stackoverflow“你做错了”答案的一部分......

然而,如果你真的“处理”了这个异常,那么重新抛出异常并没有多大意义。也许你的方法应该只返回一个失败的结果,可能包括Exception作为出错的详细项目。

答案 1 :(得分:1)

这很旧,但是我在这里有一些建议。我之前使用过一种设计模式,可以很好地完成此工作,但确实会增加所有内容的开销。

基本上,所有方法都将返回响应对象(例如Response<T>)。发生的任何异常都应该包装在响应对象中,并返回而不是引发。

public class Response<T>
{
    public T Payload { get; set; }
    public bool IsSuccessful { get; set; } = false;
    public string Message { get; set; }
    public Exception Error { get; set; }

}

public class MyService
{
    public Response<IEnumerable<Customer>> GetCustomers()
    {
        var response = new Response<IEnumerable<Customer>>();
        try
        {
            var customers = new List<Customer>()
            {
                new Customer() { CompanyName = "ABC Co." },
                new Customer() { CompanyName = "ACME" }
            };

            response.Payload = customers;
            response.IsSuccessful = true;
        }
        catch (Exception e)
        {
            response.IsSuccessful = false;
            response.Error = e;
            // A friendly message, safe to show to users.
            response.Message = "An error occurred while attempting to retrieve customers.";
        }

        return response;
    }
}

您可以冒泡而无需重新抛出异常,并进行适当处理。然后,您可以添加异常捕获以获取更多自定义的用户友好消息。

对于可以安全显示给客户端的任何错误,我还使用自定义的基本Exception类型。这样,我可以在控制器级别添加通用捕获,以传播那些准备好的错误消息。

答案 2 :(得分:0)

唔不,还没有到达那里。异常通过处理程序冒泡。 通常的方式来解决这个问题。 定义你自己的异常,然后只抓住你要处理的那些异常。

答案 3 :(得分:0)

如果您可以确定代码是在一个专门设计的try-catch块中包装的,该块是用支持异常过滤器的语言编写的,那么可以在堆栈展开之前或期间确定异常是否可能是被外围或内部阻挡。然而,这种方法的用处相当有限,特别是考虑到代码捕获和重新抛出异常的极其常见的反模式,它知道它不会解决,只是为了发现它们已经发生。

如果您的目标只是避免冗余日志记录,我建议您使用可以有效处理冗余的日志记录工具。虽然有些人可能认为最好只在外层记录一次异常,但有更多的记录机会是有好处的。如果在内层中发生异常并且中间层吞下它,则外层中的记录代码将永远不会发现它。相比之下,如果内层通过捕获异常并安排它被记录开始,那么即使中间层吞下异常,它仍然会被记录下来。