请选择 进入手机版 | 继续访问电脑版

国外大佬给出的三种处理异常的套路!

[复制链接]
admin 发表于 2020-2-8 22:25:31 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
Oh no, don't do this to me...
中文翻译:
哦,请不要这样写……
// 写一句注释跳过异常
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 - 处理异常 (;
}
.... and still, I am finding those catch blocks inside various projects. This is a great way to suppress the problem — for a short period of time. A few weeks or months later, this will become a nightmare for developers. Walking through the old log files and trying to figure out what went wrong is definitely not that most people want to do. Therefore, let's avoid that.
The first rule is that catch blocks are here to handle exceptional situations. Logging exceptions and moving on is not considered as handling. The only case when it makes sense to suppress exception is during the closing of the resource after a prior exception (this case isn't covered within this article; if you are interested, then here is an old yet still very good blog post written by McDowell).
There are three basic patterns of how to handle exceptions: translate, retry, and recover.
Translate is often used when you have to deal with a checked exception, your method can't bubble it up, and recovery is not possible. In such cases, it is appropriate to translate it into a runtime exception and throw up. Then, the runtime exception is typically handled in the framework level. Retry is useful when dealing with unreliable services. It makes sense only if retrying makes sense fundamentally. The good example is retrying to overcome network interruptions. Recover is good when the strategy for doing that is defined. For example, you can write data to the local storage if sending over network fails. Of course, then it's necessary to define what to do with that file.
In addition, the mentioned patterns might be combined. Examples are as follows.
中文翻译:
我在各种项目中发现了这种 catch 语句。这是一种“好办法”,可以在短期内掩盖问题。然而几周或几个月后,这些代码将成为开发人员的噩梦。绝大多数人可不想读日志查问题。因此,还是让我们避免这种情况。
规则一:catch 语句是用来处理异常的,把异常记到日志里然后继续执行不算处理。唯一的例外是,在发生异常后关闭资源(本文不讨论这种情况;如果感兴趣,可以参考这篇 McDowell 的博客,虽然写的时间比较早,但内容很不错)。
有三种处理异常的基本模式:转换(translate)、重试(retry)和恢复(recover)。
转换经常用于处理受检异常(checked exception),在方法中异常无法抛出,并且无法恢复时使用。在这种情况下,将其转换为运行时异常(runtime exception)而后抛出是最合适的做法。接下来,运行时异常通常由框架处理。在处理不可靠的服务时,重试非常有用,前提是重新尝试有意义。一个很好的例子就是网络中断重试。如果定义了这种策略,那么就能够恢复到正常状态。例如,如果通过网络发送数据失败,可以将数据写入本地存储。当然,这时就必须定义如何处理该文件。
此外,上面提到的模式可以组合,比如像下面这个例子如下。
// 转换
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);
    }
}
If everything fails, then this way will at least guarantee that you will be aware of the problem. In addition, it will provide you always the true cause of the issue; therefore, you will be able to quickly identify where the problem is!
Happy handling!
中文翻译:
如果一切都失败了,那么上面这种方法至少可以确保你能意识到问题所在。此外,它还提供了问题的真正原因,从而让你能快速定位问题。
祝编程快乐!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝0

帖子512

发布主题
这里有你想要的资源,懂您所要!

扫描二维码关注我们

© 2019 YOU友共享资源网版权所有 ( 蜀ICP备19016380号-1 )