如何返回正确的结果和错误列表

时间:2012-10-29 12:42:27

标签: java error-handling

我对以下方法的设计感到困惑:

Map<String, BigDecimal> foo(Parameter p){ ... }

此方法采用复杂的Parameter并返回地图名称 - &gt;值。在许多情况下,基于参数的某些基础calue,结果映射将是相同的,此外,只有少数不同的映射可以返回,因此这些将被缓存。但是,在最初创建映射时,可能存在不同类型的错误 - 某些字符串值可能不正确,某些值可能是&lt;因此应该跳过0等等。这些错误可能具有不同的性质。我想返回这个地图,但是当执行每个地图的初始化时,也能够标记这些错误,理想情况下只能标记一次。最干净的方法是什么?

2 个答案:

答案 0 :(得分:5)

这是一个相当不寻常的要求 - 如果可以生成有效的结果,尽管存在内部错误,您应该返回该结果;如果没有,抛出异常。

但如果您确实想要返回这些附加信息,那么我发现您有两种可供选择:

  1. 面向对象,可变状态。当您运行foo()时,会累积某些字段中的内部错误。公开额外的getFooErrors()方法以允许调用者检查发生的情况。如果您需要告诉来电者这些错误对结果地图质量的影响程度,可能还需要getFooErrorSeverity()方法。
  2. <强>不可变/功能即可。从上面返回信息(例外,可能是严重性分数)作为方法的一部分。而不是返回Map<String, BigDecimal>,而是返回包含地图的对象以及异常详细信息。 E.g:

    public class FooResult {
        public final Map<String, BigDecimal> result;
        public final List<Throwable> errors;
        public final int errorSeverity;
    
        // Constructor elided
    }
    
  3. 第一种方法类似于java.io.PrintWriter在标准库中的工作方式。它吞下其I / O方法遇到的任何IOExceptions,并公开checkError()方法以允许调用者查看编写器是否遇到任何异常。

    我更喜欢第二种,因为它不会影响线程安全性,它会为客户端预先提供所有信息,并且它与遇到错误的范围整齐地结合在一起。

答案 1 :(得分:2)

没有一种正确的方法可以做到这一点,但是如何创建包含地图和错误列表的特殊类FooResult(尽管我宁愿将其称为警告,因为通常会报告不可恢复的错误例外),例如:

FooResult foo(Parameter p){ ... }

class FooResult {
  Map<String, BigDecimal> result;
  List<Error> errors;
}

其中Error可以是包含您需要的所有错误信息的类(例如,代码,消息,异常等),例如:

class Error {
  int code;
  String message;
  Throwable cause; // optional, depending on error
  // ...
}

或者,Error的列表可以作为参数传递,并在必要时由方法填充,例如:

Map<String, BigDecimal> foo(Parameter p, List<Error> errors) { 
  ... 
  if (error) {
    errors.add(new Error(10, "Bad error"));
  }
}