Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to differentiate SocketTimeoutException

Tags:

java

exception

I need to handle it differently when I catch SocketTimeoutException. The only thing I find is to rely on the getMessage(). So far, I found two:

java.net.SocketTimeoutException: connect timed out
java.net.SocketTimeoutException: Read timed out

Are the messages (connect timed out, Read timed out) hardcoded? Where are they generated? At least any constant values for those messages?

like image 653
Wei Zhu Avatar asked Mar 01 '13 19:03

Wei Zhu


People also ask

How do I resolve SocketTimeoutException?

Using try/catch/finally If you are a developer, so you can surround the socket connection part of your code in a try/catch/finally and handle the error in the catch. You might try connecting a second time, or try connecting to another possible socket, or simply exit the program cleanly.

What is a SocketTimeoutException?

As you may suspect based on the name, the SocketTimeoutException is thrown when a timeout occurs during a read or acceptance message within a socket connection.

How do I resolve Java net SocketTimeoutException connect timed out?

A possible solution for this problem within the Tomcat web application is to modify the CONTEXT. XML file, and modify the CONNECTOR definition that governs the workstation browser connectivity to the Tomcat server. Specifically, modify the connectionTimeout value. Increase this value to suppress the error condition.


2 Answers

You can check Socket.isConnected. But since exceptions are thrown by different methods it is better to use two catch blocks with different actions.

 try {
       socket.connect(address);
    } catch (SocketTimeoutException e) {
        throw new SocketConnectionException(e);
    }
    try {
       socket.getInputStream();
       ...
    } catch (SocketTimeoutException e) {
        throw new SocketReadException(e);
    } 
like image 140
ijrandom Avatar answered Sep 17 '22 00:09

ijrandom


So, here is my claim to fame. Here, we're walking down the StackTrace, looking for the origin-method of the Exception.

public class ExceptionOriginTracing {

    public static void main(String[] args){
        try {
            originOne();
            originTwo();
        } catch (Exception e){
            // Now for the magic:
            for (StackTraceElement element : e.getStackTrace()){
                if (element.getMethodName().equals("originOne")){
                    System.out.println("It's a read error!");
                    break;
                } else if (element.getMethodName().equals("originTwo")){
                    System.out.println("It's a write error!");
                    break;
                }
            }
        }
    }

    public static void originOne() throws Exception{
        throw new Exception("Read Failed...", null);
    }

    public static void originTwo() throws Exception{
        throw new Exception("Connect failed...", null);
    }
}

The difference to parsing the message given by the Exception is, that a simple string is more likely to change, than the name of the actual method.

Aside from that, this is not an optimal solution! But sadly, there is no optimal solution here.

Also, with this approach, extra care must be taken when source obfuscation is used, which will change the method-names and therefor the return value of getMethodName().


The right way when designing something like this would be to wrap the exception in a new Exception, which provided methods to actually find out the real origin by using a flag or an enum.

Parsing a message/StackTrace always feels dirty and is subtable to break in future releases!

like image 43
Lukas Knuth Avatar answered Sep 18 '22 00:09

Lukas Knuth