Подтвердить что ты не робот

Как отличить SocketTimeoutException

Мне нужно обработать его по-разному, когда я поймаю SocketTimeoutException. Единственное, что я нахожу, это полагаться на getMessage(). До сих пор я нашел два:

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

Являются ли сообщения (время ожидания подключения, время ожидания чтения) жестко запрограммированным? Где они сгенерированы? По крайней мере, любые постоянные значения для этих сообщений?

4b9b3361

Ответ 1

Итак, вот моя претензия на славу. Здесь мы идем вниз по StackTrace, ища метод-исходник Исключения.

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 a read error!");
                    break;
                } else if (element.getMethodName().equals("originTwo")){
                    System.out.println("It 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);
    }
}

Разница в анализе сообщения, заданного Исключением, заключается в том, что простая строка с большей вероятностью изменится, чем имя фактического метода.

Кроме того, это не оптимальное решение! Но, к сожалению, здесь нет оптимального решения.

Кроме того, при таком подходе следует проявлять особую осторожность при использовании обфускации источника, что изменит имена методов и, следовательно, возвращает значение getMethodName().


Правильный способ создания чего-то подобного заключается в том, чтобы обернуть исключение в новое исключение, которое предоставило методы для фактического определения реального происхождения с помощью флага или перечисления.

Разбор сообщения /StackTrace всегда чувствует себя грязным и подзаголовка разбивается на будущие выпуски!

Ответ 2

Вы можете проверить Socket.isConnected. Но поскольку исключения выбраны разными способами, лучше использовать два блока catch с разными действиями.

 try {
       socket.connect(address);
    } catch (SocketTimeoutException e) {
        throw new SocketConnectionException(e);
    }
    try {
       socket.getInputStream();
       ...
    } catch (SocketTimeoutException e) {
        throw new SocketReadException(e);
    } 

Ответ 3

Они исходят из разных методов. "Тайм-аут соединения" происходит при вызове connect(), неявно или явно; "read timed out" происходит при вызове read() или одного из его символов. Таким образом, вы можете различать просто наличие двух разных блоков catch. Но в любом случае вы, вероятно, собираетесь закрыть соединение...