adam bien's blog

Clearer JAX-RS 2.1 Client Error Messages 📎

If you try to connect with a too slow HTTP endpoint or too ambitious configured timeouts:


import java.util.concurrent.TimeUnit;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import org.junit.Before;
import org.junit.Test;

public class JAXRSClientExceptionTest {

private WebTarget airhacksTarget;

@Before
public void initClient() {
    Client client = ClientBuilder.newBuilder().
    
            connectTimeout(2, TimeUnit.MILLISECONDS).
            readTimeout(2, TimeUnit.MILLISECONDS).
                
            build();
    this.airhacksTarget = client.target("https://jakarta.ee");
}

@Test
public void connect() {
    this.airhacksTarget.request().get(String.class);
}
}

You will get the ProcessingException with wrapped cause:

    javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: connect timed out
	at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:284)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:278)
	at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$1(JerseyInvocation.java:767)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:229)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:414)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:765)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:428)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:324)
	at com.airhacks.JAXRSClientExceptionTest.connect(JAXRSClientExceptionTest.java:32)
    (...)	
Caused by: java.net.SocketTimeoutException: connect timed out
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
(...)

A try-catch block:


@Test
public void connectWithNicerError() {
    try {
        this.airhacksTarget.request().get(String.class);
    
    } catch (ProcessingException ex) {
		Throwable cause = ex.getCause();
        String errorName = cause.getClass().getSimpleName(); //null checks skipped
        String message = errorName + ":" + cause.getMessage();
        System.out.println(message);
        //rethrow or handle
    }
        
}

...makes the error message clear:

SocketTimeoutException:connect timed out or SocketTimeoutException:Read timed out

See you at "Build to last" effectively progressive applications with webstandards only -- the "no frameworks, no migrations" approach, at Munich Airport, Terminal 2 or effectiveweb.training (online).