如何区分 SocketTimeoutException

2022-09-03 02:58:53

当我抓住.cing时,我需要以不同的方式处理它。我唯一发现的是依靠.到目前为止,我发现了两个:SocketTimeoutExceptiongetMessage()

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

消息(连接超时、读取超时)是否经过硬编码?它们在哪里生成?这些消息至少有任何常量值?


答案 1

您可以选中 Socket.isConnected。但是,由于异常是由不同的方法引发的,因此最好使用两个具有不同操作的 catch 块。

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

答案 2

所以,这是我成名的主张。在这里,我们沿着 StackTrace 走下去,寻找 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);
    }
}

与分析 Exception 给出的消息的不同之处在于,与实际方法的名称相比,简单字符串更有可能更改。

除此之外,这不是一个最佳解决方案!但可悲的是,这里没有最佳解决方案。

此外,使用此方法时,在使用源混淆时必须格外小心,这将更改方法名称,从而更改 返回值。getMethodName()


在设计类似的东西时,正确的方法是将异常包装在一个新的 Exception 中,它提供了通过使用标志或枚举来实际找出真正起源的方法。

解析消息/StackTrace总是感觉很脏,并且在将来的版本中会破坏子表!