美文网首页
第七十五条:在细节消息中包含失败-捕获信息

第七十五条:在细节消息中包含失败-捕获信息

作者: Js_Gavin | 来源:发表于2021-04-02 15:11 被阅读0次

    当程序由于未捕获的异常而失败的时候,系统会自动打印出该异常的堆栈轨迹。在堆栈轨迹中包含该异常的字符串表示法,即它的toString方法的调用结果。它通常包含该异常的类命,紧随其后的是细节消息(detailMessage)。通常,这只是程序员或者网站可靠性工程师在调查软件失败原因时必须检查的信息。如果失败的情形不容易重现,要想获得更多的信息会非常困难,甚至是不可能。因此,异常类型的toString方法应该尽可能多的返回有关失败原因的信息,这一点特别重要。换句话说,异常的字符串表示法应该捕获失败,以便于后续进行分析

    为了捕获失败,异常的细节信息应该包含“对该异常有贡献”的所有参数和域的值。例如,IndexOutOfBoundsException异常的细节消息应该包含下界、上界以及没有落在界内的下标值。该细节消息提供了许多关于失败的信息。这三个值任何一个或者全部都有可能是错的。实际的下标值可能小于下界或者等于上界("越界错误"),或者它可能是个无效值,太小或太大。下界也有可能大于上界(严重违反内部约束条件的一种情况)。每一种情形都代表了不同的问题,如果程序员知道应该去查找哪些错误,就可以极大的加速诊断过程。

    对安全敏感的信息有一条忠告。由于在诊断和修正软件问题的过程中,许多人都可以看见堆栈轨迹,因此千万不要在细节消息中包含密码、密钥以及类型的消息

    虽然在异常的细节消息中包含所有相关的数据是非常重要的,但是包含大量的描述信息往往没有什么意义。堆栈轨迹的用途是与源文件结合起来进行分析,它通常抛出该异常的确切文件行数,以及堆栈所有其他方法调用所在的文件和行数。关于失败的冗长描述信息通常是不必要的,这些信息可以通过阅读源代码而获得。

    异常的细节消息不应该与"用户层次的错误消息"混为一谈,后者对于最终用户而言必须是可理解的。与用户层次的错误消息不同,异常的字符串表示法主要是让程序员或者网站可靠工程师用来分析失败的原因。因此,信息的内容比可读性重要得多。用户层次的错误消息经常被本地化,而异常的细节消息则几乎没有被本地化。

    为了确保在异常的细节消息中包含足够的失败-捕捉信息,一种办法是在异常的构造器而不是字符细节消息中引入这些信息。然后,有了这些信息,只要把它们放到消息描述中,就可以自动产生细节消息。例如,IndexOutOfBoundsException使用如下构造器代替String构造器:

    /**
    * Constructs an IndexOutOfBoundsException.
    *
    * @param lowerBound the lowest legal index value
    * @param upperBound the highest legal index value plus one 
    * @param index the actual index value
    */
    public IndexOutOfBoundsException(int lowerBound, int upperBound,
    int index) {
    // Generate a detail message that captures the failure
      super(String.format("Lower bound: %d, Upper bound: %d, Index: %d", lowerBound, upperBound, index));
    // Save failure information for programmatic access 
      this.lowerBound = lowerBound;
      this.upperBound = upperBound;
      this.index = index;
    }
    

    从Java9开始,IndexOutOfBoundsException终于获得了一个构造器,它可以带一个类型为int的index参数值,但遗憾的是,它删除了lowerBound和upperBound参数。更通俗的说,Java平台类库并没有广泛的使用这种做法,但是,这种做法仍然值得大力推荐。它使程序员更加易于抛出异常以捕获失败。实际上,这种做法使程序员不想捕获异常都难!这种做法可以有效的把代码集中起来放在异常类中,由这些代码对异常类自身的异常产生高质量的细节消息,而不是要求类的每个用户都多余的产生细节消息。

    正如第70条中所建议的,为异常的失败 - 捕获信息(在上述例子中为lowerBound、upperBound和index)提供一些访问方法是合适的。提供这样的访问方法对受检异常,比对未受检异常更为重要,因为失败 - 捕获信息对于从失败中恢复是非常有用的。程序员希望通过程序的手段来访问未受检异常的细节,这很少见(尽管也可以想象)。然而,即使对未受检异常,作为一般原则提供这些访问方法也是明智的(详见12条)。

    相关文章

      网友评论

          本文标题:第七十五条:在细节消息中包含失败-捕获信息

          本文链接:https://www.haomeiwen.com/subject/nqtqkltx.html