上下文异常中的上下文属性
我不断重复同样的错误。
因此,该停止并制定规则以防止这种情况了。
错误不是致命的,但很烦人。
当查看生产日志时,经常会看到类似"File doesn't exist"
,并且我问自己:什么文件?
它应该在哪里存在?
服务器尝试使用它做什么?
崩溃前一秒钟发生了什么?
日志中没有答案,这完全是我的错。
我要么1)不重新抛出,要么2)在不提供上下文的情况下重新抛出。
两者都是错的。
代码如下所示:
if (!file.exists()) {throw new IllegalArgumentException("File doesn't exist");
}
它也可能看起来像这样:
try {Files.delete(file);
} catch (IOException ex) {throw new IllegalArgumentException(ex);
}
这两个示例都说明了处理涉及异常并报告异常的情况的风格不足。 怎么了 异常消息不够彻底。 它们根本不包含来自其来源的任何信息。
他们应该这样看:
if (!file.exists()) {throw new IllegalArgumentException(String.format("User profile file %s doesn't exist",file.getAbsolutePath()));
}
第二个示例应如下所示:
try {Files.delete(file);
} catch (IOException ex) {throw new IllegalArgumentException(String.format("Can't delete user profile data file %s",file.getAbsolutePath()),ex);
}
看到不同? 这看起来像是冗余代码,但事实并非如此。 当然,当我编写所有这些内容时,我并不真正在乎日志和异常。 我并不是真的希望这个文件不存在。
但是我应该。
应该有一条规则:每次我们抛出或重新抛出异常消息时,都必须尽可能详细地描述问题。
当然,我们不能忘记安全性和冒着将任何敏感信息(例如密码,信用卡号等)放入异常消息中的风险。此外,必须在更高级别上尽可能多地向异常捕获程序公开这些信息。
抛出异常实际上是将问题升级到更高级别的管理。 想象一下,老板要我安装新服务器。 几小时后我回到他身边说:“我失败了;我失败了。 抱歉。” 听起来很奇怪。 他会要求更多细节。 为什么我失败了? 到底出了什么问题? 可以做不同的事情吗? 等等。
这样的代码实际上是对客户不尊重的标志:
throw new IllegalArgumentException("File doesn't exist"
);
我必须更加详细,并提供更多细节。
我不是一个人犯这个错误。 我到处都看到它,这确实使调试变得困难,尤其是在生产中,几乎不可能立即重现该问题。
因此,请在您的异常消息中更加详细。 我将在代码中执行相同的操作:)
还有一件事,然后再走。 在大多数OOP语言中,未检查异常是不幸的 ,这意味着捕获异常不是强制性操作。 尽管如此,我还是建议您始终捕获,添加上下文并重新抛出它们。 这似乎是纯噪声,但事实并非如此! 只是使您的方法更小,并确保从它们发出的所有异常都具有有关其来源的足够信息。 您将为自己和其他人带来很大的帮助。
翻译自: https://www.javacodegeeks.com/2015/12/throwing-exception-without-proper-context-bad-habit.html
上下文异常中的上下文属性