有关构造自定义异常类型的建议

时间:2017-01-06 15:46:47

标签: java exception exception-handling

我不确定如何最好地构建自定义异常。假设我有一种情况,其中有一些库会抛出自己的自定义异常类,其中包含自定义字段:

public class CustomException extends RuntimeException {
  private final String additionalInfo;

  public CustomException(String message, String additional) {
    super(message);
    this.additionalInfo = additional;
  } 

  public String getAdditionalInfo() {
    return additionalInfo;
  }
}

处理这个问题非常简单:

try {
  something();
} catch (CustomException e) {
  LOGGER.error(e.getMessage());
  LOGGER.error(e.getAdditionalInfo());
}

到目前为止,这么好,但是当它在某种服务中包含多层深层并以这种方式处理时呢?

// in a subclass of a theoretical ServiceHandler interface
public void handle() throws OperationFailedException {
  try {
    something();
  } catch (RuntimeException e) {
    throw new OperationFailedException("The operation failed.", e);
  }
}

在callstack的下方,服务调度代码捕获此新异常,将通用(安全)消息返回给外部调用者,并在内部的某处记录完整的异常跟踪,包括原因(我们的原始自定义异常类型)。现在的问题是日志中缺少CustomException中的额外字段,因为日志框架只对getMessage()和callstack感兴趣。

try { // call to the ServiceHandler
  sendResponseToClient(findServiceHandler(rpcName).handle(args));
} catch (Throwable th) { 
  LOGGER.error(th);
  sendErrorToClient("An internal error occurred with incident ID: <id>");
}

我可以想到一些解决方案:

1)使记录服务异常的事物知道这个特殊的异常类型,以便它可以记录它

2)覆盖getMessage(),以便返回super.getMessage() + getAdditionalInfo()

3)所有调用的东西都可以抛出其中一个我将其重新抛出其他内容并将其他字段添加到消息中:

try { 
  something();
} catch (CustomException ce) {
  throw new OperationFailedException("The operation failed because " + ce.getAdditionalInfo(), ce);
} catch (RuntimeException e) {
  throw new OperationFailedException("The operation failed", e);
}

实际的用例是一个包含几百个函数的本机代码库,它们在整个应用程序中随处可见。这种异常类型是一般的&#34; api以一种未经预料的方式失败了#34;错误,所以它没有被检查,并且在日常操作中我不会期望看到一个。

(1)似乎很容易在将来错过新类型,如果在一年内有人添加了他们需要注意的另一种自定义异常类型所有可能记录它并在那里写入相应处理程序代码的地方。 (2)感觉有点可疑,因为您正在使用一条消息创建例外,并收到不同的消息。在(3)中应用模式似乎会产生很多混乱,特别是如果我有一些这些自定义异常类型需要担心。

我应该使用哪种方法?还有其他选择,或者你会建议重组一些事情来解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

异常基本上有两种情况:

1)你可以恢复

2)你不能,你只想让你的申请退出

如果可以恢复,您可能需要考虑使用已检查的异常。 然后你来处理异常,编译器会告诉你在哪里捕获它。

否则,如果应用程序崩溃,您可能希望将此附加信息添加到您为超类构造函数提供的消息中。