有没有办法检查是否在更高的应用程序级别上处理了异常以跳过日志记录并重新抛出?像这样,例如:
try
{
// Execute some code
}
catch (Exception e)
{
if(!ExceptionIsHandled())
LogError(e);
throw e;
}
有没有办法检查是否在更高的应用程序级别上处理了异常以跳过日志记录并重新抛出?像这样,例如:
try
{
// Execute some code
}
catch (Exception e)
{
if(!ExceptionIsHandled())
LogError(e);
throw e;
}
没有什么我知道的。如果您致力于这种设计(见最后的注释),您可以为某种异常编写一个包装器,HandledException
并使其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 块中,该块是用支持异常过滤器的语言编写的,那么就有可能在堆栈展开之前或期间确定异常是否可能被那个捕获外部块或内部块。然而,这样做的用处是相当有限的,特别是考虑到代码捕获和重新抛出异常的极其常见的反模式,它知道它不会解决,只是为了找出它们发生的目的。
如果您的目标只是避免冗余日志记录,我建议您应该使用可以有效处理冗余的日志记录工具。虽然有些人可能会争辩说,在外层只记录一次异常更好,但拥有更多记录机会是有好处的。如果内层发生异常并且中间层吞下了它,那么外层内的日志记录代码将永远不会发现它。相比之下,如果内层从捕获异常开始并安排它被记录下来,那么即使中间层吞下异常,它发生的事实仍然可以被记录下来。
嗯,不,还没有到那里。异常通过处理程序冒泡。通常的方法来解决这个问题。定义您自己的异常,然后只捕获您要处理的异常。