【发布时间】:2015-06-23 06:25:57
【问题描述】:
public void DeployCourse(Course course, Client client)
{
if (course == null) throw new ArgumentNullException("Course cannot be null");
if (client == null) throw new ArgumentNullException("Client cannot be null");
try
{
_ftp.Transfer(client.Server.IPAddress, course.PackageUrl, course.CourseName);
}
catch (Exception e)
{
var newException = new Exception(String.Format(
"Error deploying Course: {0} to Client: {1}. See inner exception for more details",
course.CourseName, client.Name), e);
throw newException;
}
}
我从来没有真正理解什么是“好的”异常处理。一个快速的谷歌搜索表明,几乎一致,人们同意在调用堆栈深处捕获和重新抛出异常是不好的。上面,我有一个我正在编写的代码的示例。这在典型的调用堆栈中非常低。我这样做是因为如果没有此代码,很难准确找到未能部署的课程。我的问题是,如果我在许多(如果不是全部)方法中做了类似的事情,为异常添加更多上下文,为什么这会被视为反模式?
谢谢!
【问题讨论】:
-
不,不是这样。编写 catch (Exception ex) { throw ex; 的程序员} 犯下那个罪。太常见了。
-
我相信真正的反模式是抛出异常,然后将其作为特殊的返回码而不是真正的异常情况来捕获。包装异常以提供更多详细信息是很好的 IMO。
-
我同意这不是一个糟糕的模式。您确保抛出的异常在逻辑上连接到被调用的方法,这对于您的 API 用户来说是一个很好的属性。而且您保留旧的异常以帮助诊断。当然有办法滥用这种模式,但我认为这里显示的代码是合理的。
-
现在,您的代码中有一个错误。传递给 ArgumentNullException 的 ctor 的字符串应该是违规参数的名称,而不是信息性消息。如果您想要一条消息,那么它应该是(名称,消息)。 注意 ArgumentException 是 (message, name),ArgumentNullException 是 (name, message) THANKS MICROSOFT.
-
您还应该抛出比“新异常”更好的东西。制作一个新的 CourseDeploymentFailureException 或类似的。
标签: c# exception-handling