Changeset 18532 in josm

2022-08-12T00:01:15+02:00 (6 months ago)

Fix #22160: Retry on SocketException: Unexpected end of file from server

This allows additional exceptions to force a retry. Specifically, the
following subclasses of SocketException were considered:

  • BindException -- shouldn't be thrown, "Signals that an error occurred

while attempting to bind a socket to a local address and port. Typically,
the port is in use, or the requested local address could not be assigned."
This will be raised if it is ever encountered.

  • ConnectException-- replacing that here, "Signals that an error occurred

while attempting to connect a socket to a remote address and port.
Typically, the connection was refused remotely (e.g., no process is
listening on the remote address/port)."

  • ConnectionResetException -- "Thrown to indicate a connection reset"

This seems to be a Java internal class. It is rethrown.

  • NoRouteToHostException -- "Signals that an error occurred while attempting

to connect a socket to a remote address and port. Typically, the remote
host cannot be reached because of an intervening firewall, or if an
intermediate router is down."

  • PortUnreachableException -- "Signals that an ICMP Port Unreachable message

has been received on a connected datagram."

SocketException is only thrown in one location in the JDK source code, but
just in case someone decided to throw the exception in a library, we
additionally check that the message matches that from the JDK source. This is,
unfortunately, a bit more fragile than it should be.

1 edited


  • trunk/src/org/openstreetmap/josm/io/

    r18283 r18532  
    769772                    throw new OsmApiException(retCode, errorHeader, errorBody);
    770773                }
    771             } catch (SocketTimeoutException | ConnectException e) {
    772                 if (retries-- > 0) {
     774            } catch (SocketException | SocketTimeoutException e) {
     775                /*
     776                 * See #22160. While it is only thrown once in JDK sources, it does have subclasses.
     777                 * We check for those first, the explicit non-child exception, and then for the message.
     778                 */
     779                boolean validException = e instanceof SocketTimeoutException
     780                        || e instanceof ConnectException
     781                        || e instanceof NoRouteToHostException
     782                        || e instanceof PortUnreachableException
     783                        || (e.getClass().equals(SocketException.class) &&
     784                            "Unexpected end of file from server".equals(e.getMessage()));
     785                if (retries-- > 0 && validException) {
    773786                    continue;
    774787                }
Note: See TracChangeset for help on using the changeset viewer.