让异常处理代码更健壮

2019-11-15 16:19:01 浏览数 (1)

来源:dzone.com/articles/good-exception-handling

像冠军一样处理异常。

哦,请不要这样写……

代码语言:javascript复制
// 写一句注释跳过异常
try {
    throw new IOException("Made up");
} catch (IOException e) {
    // 跳过
}
// 记到日志里,继续处理
try {
    throw new IOException("Made up");
} catch (IOException e) {
    log.error("blah blah blah", e);
}
// 标记 TODO,不做任何处理
try {
    throw new IOException("Made up");
} catch (IOException e) {
    // TODO - 处理异常 (;
}

我在各种项目中发现了这种 catch 语句。这是一种“好办法”,可以在短期内掩盖问题。然而几周或几个月后,这些代码将成为开发人员的噩梦。绝大多数人可不想读日志查问题。因此,还是让我们避免这种情况。

规则一:catch 语句是用来处理异常的,把异常记到日志里然后继续执行不算处理。唯一的例外是,在发生异常后关闭资源(本文不讨论这种情况;如果感兴趣,可以参考这篇 McDowell 的博客,虽然写的时间比较早,但内容很不错)。

有三种处理异常的基本模式:转换(translate)重试(retry)恢复(recover)

转换经常用于处理受检异常(checked exception),在方法中异常无法抛出,并且无法恢复时使用。在这种情况下,将其转换为运行时异常(runtime exception)而后抛出是最合适的做法。接下来,运行时异常通常由框架处理。在处理不可靠的服务时,重试非常有用,前提是重新尝试有意义。一个很好的例子就是网络中断重试。如果定义了这种策略,那么就能够恢复到正常状态。例如,如果通过网络发送数据失败,可以将数据写入本地存储。当然,这时就必须定义如何处理该文件。

此外,上面提到的模式可以组合,比如像下面这个例子如下。

代码语言:javascript复制
// 转换
try {
    throw new IOException("Made up");
} catch (IOException e) {
    throw new RuntimeException(e);
}
// 重试5次后放弃
boolean end = false;
int count = 0;
while (end == false) {
    try {
        // 发送信息
        if (true) {
            throw new MessagingException("Made up");
        }
        end = true;
    } catch (MessagingException e) {
        if (count >= 5) {
            // 尝试5次放弃。
            throw new RuntimeException("was not able to send message even after five tries", e);
        }
          count;
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e1);
        }
    }
}
// 恢复:如果传输失败记录到文件
try {
    // 发送信息
    throw new MessagingException("Made up");
} catch (MessagingException e) {
    try {
        // 写文件
        throw new IOException("Made up");
    } catch (IOException e1) {
        // 如果写文件失败,不再进行恢复
        throw new RuntimeException(e1);
    }
}

如果一切都失败了,那么上面这种方法至少可以确保你能意识到问题所在。此外,它还提供了问题的真正原因,从而让你能快速定位问题。

祝编程快乐!

0 人点赞