Java 异常消息是否有约定?

Is there a convention for Java exception messages?

我一直在尝试抛出异常,并附带更多信息。我把它写成多行,因为我想让它冗长并帮助调试。

throw new RuntimeException("Something failed.\n" + 
    "Please provide another dependency on this class\n\n" + 
    "  MyClass object = new MyClass(depdencyA, dependencyB)");

但是我应该这样做吗?似乎很多例外都是一行,但我觉得它不够冗长。

仅供参考,我正在编写 Gradle 插件,所以如果还有不同的约定,请告诉我。

如果有,请出示参考文献或权威机构如 Oracle 的文档。

没有通用约定。然而:

  1. 像这样扔 RuntimeException 通常不是一个好主意。

  2. 如果针对普通用户,冗长的异常消息可能会让人不知所措。

  3. 无法保证异常消息中嵌入的标记(如换行符、制表符等)将得到合理处理。 (首先,您无法预测显示消息的 window 的字符宽度,以及(甚至)是否会使用固定宽度的字体。)

  4. 国际化....

对于Gradle的情况,你可以(应该)检查一下其他插件做了什么,也可以看看Gradle如何处理多行异常消息。


处理为诊断提供额外详细信息的另一种方法是使用应用程序的记录器记录 INFO 或 DEBUG 事件的详细信息... 抛出异常之前。

异常(和异常消息)应尽可能具体和简洁。

他们应该提供足够的信息来查明问题并告知用户(或管理员)如何解决问题。

您的示例在这些方面失败了:

  1. RuntimeException 非常通用 - select 更具体的异常类型(可能是一些现有的异常类型,也可能是您创建的某些异常类型)
  2. "Something failed." 是不必要的——如果一切正常你就不会抛出异常
  3. "Please provide another dependency on this class" - 如果您的 class 需要特定数量的依赖项,请告诉用户:"Only 2 of 5 dependencies supplied"。或者告诉用户缺少什么依赖:"No DataSource found"
  4. "MyClass object = new MyClass(depdencyA, dependencyB)" - 这部分假设用户端有一些调用方式。如果使用反射或通过方法引用调用您的构造函数/方法怎么办?
  5. 抛出异常的确切位置也包含在堆栈跟踪中 - 不要在异常消息中再次包含此信息