For example, I have a TCP server:
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;
}
}
If it ServerSocket::acceptthrows SocketException: Too many open files, I would only like to register an exception, but continue to work with the TCP server thread and try again after a few seconds of sleep. But in any other cases, the server thread must be executed.
Is it safe to use a message from an exception and make sure that the exception message is always the same for each implementation? Or is there a better way to detect this?
Decision
Thanks guys for the great answers. In my example, you can find only SocketException, not any subclasses. Neither ServerSocket nor SocketException have a method getStatusCode(). Therefore, I chose the following simplified solution for my example:
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;
}
}