根据Exception的消息控​​制程序流是否是个好主意?

时间:2018-02-21 10:09:54

标签: java sockets serversocket

例如我有一个TCP服务器:

ServerSocket serverSocket = new ServerSocket(12345)
boolean doAccept = true;
while (doAccept) {
    try {
        serverSocket.accept();
    } catch (SocketException e) {
        if (serverSocket.isClosed()) {
            LOGGER.info("Server stopped.", e);
            doAccept = false;
        } else if (e.getMessage().equals("Too many open files")) {
            LOGGER.warn("Unable to accept. Will retry in 5 seconds.", e);
            Thread.sleep(5_000);
        } else {
            LOGGER.error("Socket error.", e);
            doAccept = false;
        }
    } catch (IOException e) {
        LOGGER.error("I/O error.", e);
        doAccept = false;
    }
}

如果ServerSocket::accept抛出SocketException: Too many open files,我只想记录异常,但继续运行我的TCP服务器线程,并在几秒钟睡眠后重试接受。但在任何其他情况下,必须完成服务器线程。

我可以安全地使用来自异常的消息,并确保每次实现时异常消息总是相同的吗?或者有更好的方法来检测它吗?

谢谢你们的回答。在我的示例中,只能捕获SocketException而不是任何子类。 ServerSocket和SocketException都没有任何getStatusCode()方法。所以我最终为我的例子选择了以下简化的解决方案:

ServerSocket serverSocket = new ServerSocket(12345)
boolean doAccept = true;
while (doAccept) {
    try {
        serverSocket.accept();
    } catch (SocketException e) {
        if (serverSocket.isClosed()) {
            LOGGER.info("Server stopped.", e);
            doAccept = false;
        } else {
            LOGGER.warn("Unable to accept. Will retry in 5 seconds.",                 LOGGER.error("Socket error.", e);
            Thread.sleep(5_000);
        }
    } catch (IOException e) {
        LOGGER.error("I/O error.", e);
        doAccept = false;
    }
}

2 个答案:

答案 0 :(得分:4)

不,这绝对是一种模式。异常消息应被视为人类可读信息,其他。它们意味着以编程方式进行评估。期。 (是的,有些系统实际上以编程方式查看消息 - 但这更像是一个"元"分析,寻找"模式",不做硬"字符串等于"检查)

事情是:这些例外情况不在您的控制之下。含义:当实施发生变化时,您不会注意到。这种消息的确切内容/布局在将来的某个时刻可能不太可能,但仍有可能发生变化。然后你的整个代码就崩溃了。

换句话说:如果您需要 distinct 错误处理,那么您的代码应该抛出 distinct 不同类型的异常。

并且为了记录:我并不是说即将推出 easy 解决方案。但是你所选择的那个,就像所说的那样,更像是反模式。

答案 1 :(得分:0)

我同意GhostCat 100%,错误消息取决于底层实现,只应用于日志记录。

如果您处理异常原因,也许您可​​以找到一个解决方案来决定在异常情况下该怎么做:

查看文档:{​​{3}}

也许你可以找到一个"太多的文件" -exception以前出现在堆栈跟踪中。