例如我有一个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;
}
}
答案 0 :(得分:4)
不,这绝对是一种反模式。异常消息应被视为人类可读信息,无其他。它们不意味着以编程方式进行评估。期。 (是的,有些系统实际上以编程方式查看消息 - 但这更像是一个"元"分析,寻找"模式",不做硬"字符串等于"检查)
事情是:这些例外情况不在您的控制之下。含义:当实施发生变化时,您不会注意到。这种消息的确切内容/布局在将来的某个时刻可能不太可能,但仍有可能发生变化。然后你的整个代码就崩溃了。
换句话说:如果您需要 distinct 错误处理,那么您的代码应该抛出 distinct 不同类型的异常。
并且为了记录:我并不是说即将推出 easy 解决方案。但是你所选择的那个,就像所说的那样,更像是反模式。
答案 1 :(得分:0)
我同意GhostCat 100%,错误消息取决于底层实现,只应用于日志记录。
如果您处理异常原因,也许您可以找到一个解决方案来决定在异常情况下该怎么做:
查看文档:{{3}}
也许你可以找到一个"太多的文件" -exception以前出现在堆栈跟踪中。