java—创建一个可恢复的错误接口会比在“catch”中处理恢复更有效吗

uelo1irk  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(301)

关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**更新这个问题,这样就可以通过编辑这篇文章用事实和引文来回答。

上个月关门了。
改进这个问题
注意这个问题是基于观点的,所以我在这里用更实际的方法来回答
因此,正如标题所说,我不确定是应该尝试实现可恢复的错误类,还是继续尝试在 catch 阻止。
一些psuedo代码演示:

// more or less what I have now
postToServer(data) {
    try {
        socket.write(data)
    }
    //Interrupted being a custom exception
    catch(Interrupted ex) {
        //happened twice is a common static method on all custom exceptions that returns a boolean indicating if the last thrown error is the same as this one
        if(Interrupted.happenedTwice(ex)) throw ex;
        else postToServer(data);
    } 
    //another custom exception indicating that the network is unreachable
    catch(NetworkDrop ex) {
        if(!NetworkDrop.happenedTwice(ex) && !reconnectToServer()) throw ex;
        else postToServer(data);
    }
}
//What I would like to implement
interface Recoverable {
    public void recover(Runnable) throws Exception;
}
class NetworkDrop extends Exception implements Recoverable {
    ...
    public void recover(Runnable resume) {
        if(!NetworkDrop.happenedTwice(this) && reconnectToServer()) resume.run();
        else throw this;
    } 
}
class Interrupted extends Exception implements Recoverable {
    ...
    public void recover(Runnable resume) {
        if(!Interrupted.happenedTwice(this)) resume.run();
        else throw this;
    }     
}
postToServer(data) throws Exception {
    try {
        socket.write(data)
    }
    catch(Recoverable ex) {
        ex.recover(() -> postToServer(data));
    }
}

作为示例,我希望所有的恢复代码都包含在异常中(减少重复代码,就像现在说的5个不同的方法可以调用 recover 而不是运行相同的恢复代码)。这将允许我捕获可以恢复的异常,但仍然抛出不可恢复的异常,或者在无法恢复时抛出异常。
不过,我看到了一个问题:
当中间层 Runnable 从恢复调用不返回数据?假设我正在从服务器读取而不是写入,并获得一个可恢复的异常(如networkdrop)并成功恢复。由于执行是通过recover方法上的runnable恢复的,而且runnable不返回任何内容,那么调用read的函数如何从runnable中获取数据呢?
那么,这个系统会比 catch 是谁?或者仅仅抓住可恢复的异常所带来的可读性和简洁性是一把双刃剑?
如果权衡有利于可恢复类,我将如何解决从已恢复异常获取返回值的问题?

bejyjqdl

bejyjqdl1#

异常意味着在调用堆栈上进行故障通信。抛出异常特别支持这样一个方面,即在某个嵌套调用失败后,调用方通常不想继续,而是在堆栈的更高层发出失败信号。
因此,在接收到异常后,调用方跳过其方法体的其余部分,并向其调用方发出失败信号,这种情况在所有调用堆栈中都会发生,直到找到一个具有适当 catch 阻止。

瑕疵

你的 Recoverable 例外会破坏这个系统。如果我理解正确的话,恢复是一个双重过程:异常包含如何(例如)重新建立连接的代码,而runnable由catch块提供,负责修复由于异常而跳过的代码行。
但是由于跳过的代码将来自多个嵌套调用层,我认为您不能可靠地提供有效的恢复代码。
当然,如果您准备在每一个软件层上用try/catch来包围每一行业务代码,这会变得更容易,但这与异常处理的精神相矛盾。
为了确立您的概念,您无论如何都需要确定可能发生可恢复故障的所有地方—您必须抛出 Recoverable 异常,通常 Package 一些原始的异常。这是另一种方法的关键。

建议

我建议使用不同的方法:
在所有抛出可恢复异常的地方,都知道可以从失败中恢复。因此,我将在那里实现这些知识,而不是让方法失败,而是立即应用恢复策略,这样您就可以成功地返回。
如果您担心在恢复失败时浪费太多的尝试,请查看“断路器”模式。

相关问题