例如我有一个 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 服务器线程并在之后重试接受几秒钟的 sleep 。但在任何其他情况下,服务器线程都必须完成。
我可以在这里安全地使用来自异常的消息并确保异常消息在每个实现中始终相同吗?或者存在任何更好的检测方法?
解决方案
谢谢你们的精彩回答。在我的示例中只能捕获 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;
}
}
最佳答案
不,这绝对是一个反模式。异常消息应该被视为人类可读的信息,没有其他信息。它们不旨在以编程方式评估。时期。 (是的,有些系统实际上以编程方式查看消息 - 但这更像是一种“元”分析,寻找“模式”,而不是进行硬性“字符串等于”检查)
事实是:这些异常不在您的控制之下。意思是:你不会注意到它们的实现何时发生变化。这些消息的确切内容/布局在未来的某个时候更改的可能性不大,但仍有可能。然后你的整个代码就会崩溃。
换句话说:如果您需要distinct 错误处理,那么您的代码应该抛出distinct 不同类型的异常。
郑重声明:我并不是说附近有简单的解决方案。但是你选择的那个,正如所说,更像是一种反模式。
关于java - 基于来自异常的消息来控制程序流是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48903196/