【发布时间】:2009-11-21 20:03:37
【问题描述】:
考虑这种方法(请原谅 Chuck Norris 幽默的可悲尝试:)):
public class ChuckNorrisException : Exception
{
public ChuckNorrisException()
{
}
public ChuckNorrisException(string message)
: base(message)
{
}
public ChuckNorrisException(string message, Exception cause)
: base(message, cause)
{
}
protected ChuckNorrisException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
static void ExceptionTest(double x)
{
try
{
double y = 10 / x;
Console.WriteLine("quotient = " + y);
}
catch (Exception e)
{
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
throw e;
}
}
在 resharper 中,我在“throw e”行收到一条警告,上面写着“可能有意重新抛出异常”。但显然在这种情况下这不是本意,因为 e 可以被包裹在 ChuckNorrisException 中,如果我只使用“throw”,则不会抛出包裹的异常。
我知道我可以抑制重新锐化警告,但如果我没记错的话,它将在所有场景中被关闭。我只是想知道是否有其他人遇到过这种情况。我发现的唯一解决方法是创建另一个异常变量(例如 e2),然后抛出它。这可能是我在这里能做的最好的事情了。似乎 resharper 可以检测到这个问题,并且足够聪明,知道如果 e 被修改,那么 throw e 就可以了。
谢谢。
[编辑] 对不起,我忘了一步。在抛出之前,我需要记录异常,所以我不能这样做:
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
throw e;
我必须做的:
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
LogException(e);
throw e;
【问题讨论】:
-
为什么必须在抛出异常之前记录它(即使包装在另一个异常中)?为什么调用者不能记录异常,包括内部异常?
-
例如,考虑这是否是 REST 服务中的服务方法,并且您希望在服务器日志文件中记录该异常。因此调用者(例如:Web 客户端)可以记录异常,但最好能够访问服务器日志本身的异常信息。
-
客户端无法捕获服务器上 .NET 代码中引发的异常。异常必须在服务器的某个地方被捕获,否则服务器会崩溃。
-
@Adam Ralph -“客户端无法捕获服务器上 .NET 代码中引发的异常”这不完全正确。例如,您可以将 FaultException 与 WCF 服务一起使用,并且可以在客户端上处理该 FaultException。在我们的例子中,我们在服务器上记录该异常,并在客户端捕获 FaultException 并将其也记录在那里。您可以参考这里了解更多信息:msdn.microsoft.com/en-us/library/cc949036.aspx