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

本文关键字:处理 异常 高级别 是否 检查 | 更新日期: 2023-09-27 17:57:29

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

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

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

我不知道什么。如果您致力于此设计(请参阅末尾的注释),则可以为某种类型的HandledException的Exception编写一个包装器,并使其InnerException成为抛出的那个。然后你可以让你的代码看起来像:

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

这里来了刻板的Stackoverflow"你做错了"的部分答案

但是,如果您真的"处理"了异常,那么重新抛出它就没有多大意义了。也许您的方法应该只返回一个失败结果,可能包括Exception作为错误的详细项。

这是旧的,但我在这里确实有一些输入。我以前使用过一种设计模式,它做得很好,但确实会给所有东西增加一点开销。

基本上,所有方法都会返回一个响应对象(例如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;
    }
}

您可以在不重新考虑的情况下弹出异常,并进行适当的处理。然后,您可以为更自定义的用户友好消息添加异常捕获。

对于任何可以安全显示给客户端的错误,我也使用自定义的基本异常类型。通过这种方式,我可以在控制器级别添加一个通用catch来传播那些准备好的错误消息。

不,还没有到那里。异常会通过处理程序出现。这是通常的做法。就是定义你自己的异常,然后只捕捉你要处理的异常。

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

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