下面这个例子,记录了一个 while 循环中的异常:
void read() {
while (hasNext()) {
try {
readData();
} catch {Exception e) {
// this isn’t recommend
logger.error(“error reading data“, e);
}
}
}
  如果 readData 抛出异常,而 hasNext 返回值为 true,这里将会写入无限量的日志数据。要解决这个问题的方法是确保不会记录这一切:
void read() {
int exceptionsThrown = 0;
while (hasNext()) {
try {
readData();
} catch {Exception e) {
if (exceptionsThrown < THRESHOLD) {
logger.error(“error reading data", e);
exceptionsThrown++;
} else {
// Now the error won’t choke the system.
}
}
}
}
  另一种方法是从循环中移除日志记录,并保存第一/后一个异常对象并在其它地方记录。
  4. 未捕获的处理程序
  Westeros 有后一道防御墙,而你有 Thread.uncaughtExceptionHandler。因此,尽量使用它们。如果没有安装这些处理程序,在异常抛出时,你只能获得很少有价值的上下文,同时你也无法控制在结束之前你已经将其记录,并确定记录的位置。
  请注意,即使在未捕获的异常处理程序,看起来你没有任何办法访问线程中(已终止)的任何变量,你仍然可以获得实际线程对象的引用。如果你坚持# 1步,你仍然会得到一个有意义的thread.getName()值可记录。
  5. 捕获外部调用
  每当调用一个外部的 API, JVM 异常的几率将大大增加。这包括 Web 服务、 HTTP、 DB、 文件系统、操作系统和任何其他 JNI 调用。认真对待每个调用,因为它随时会爆炸 「它很有可能发生在同样的点」。
  大多数情况下,外部 API 故障的原因是意外输入,日志中对其记录是修复代码的关键。
  在这一点上,你可以选择不记录错误,只是抛出异常也可以。在这种情况下,只要收集到调用的相关参数,并将其解析为异常错误信息。
  只要确保异常被捕获并记录在更高级别的堆栈调用即可。
  try {
  return s3client.generatePresignedUrl(request);
  } catch (Exception e) {
  String err = String.format(“Error generating request: %s bucket: %s key: %s. method: %s", request, bucket, path, method);
  log.error(err, e); //you can also throw a nested exception here with err instead.
  }