zappee zappee - 25 days ago 6
Java Question

Exception handling with Retrofit2

I am learning how to use

Retrofit2
but I am in trouble.

Is that any way to catch the
Response
object on
retrofit2.Retrofit
and throw an exception if the HTTP response code is out of the range 2xx?

I am implementing some JAX-RS rest services where my rest methods call another rest APIs to collect information and I would like to handle any HTTP error on the JAX-RS side:

public class HelloRest {

@GET("/ping")
public String ping() throws IOException {
HelloService client = HelloServiceBuilder.getInstance();
String response = client.sayHello().execute().body();
LOGGER.info(response);
}

@GET ("echo/{msg}")
public String echo(@PathParam("msg") String msg) throws IOException {
HelloService client = HelloServiceBuilder.getInstance();
String response = client.echo(msg).execute().body();
LOGGER.info(response);
return response;
}
}


First, I have realized that the
execute()
method throws IOException so I had to add it to the rest methods signatures. That is okay, I can handle it properly with JAX-RS.

But what is the best way to handle errors which is related to HTTP responses where the response code is out of the range 2xx?

I do not want to write repeated code block to check the HTTP response code any time when I use Retrofit2 like this:

Response<String> response = client.ping().execute();
int responseCode = response.code();
if (responseCode < 200 && responseCode > 299) {
throws AnyException("...");
}

String serverResponse = response.body();
...


Can I add something to the
Retrofit.Builder()
code block to handle this situation on a general way somehow?

public final class HelloServiceBuilder {

private static final String SERVICE_URL = "...";

private HelloServiceBuilder() {
// do nothing
}

public static HelloService getInstance() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVICE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.HOW-TO-CHECK-RESPONSES-HERE?
.build();

return retrofit.create(HelloService.class);
}
}

Answer Source

Am going to create my rest client class with JAX-RS. It is part of Java, I do not need to add extra dependency to my pom, works like a charm and I need to create only one class instead of 2 or more:

public final class MyRestClient {
    private static Client client = ClientBuilder.newClient();

    public static String hello() {
        String serviceUrl = "http://..../";
        String path ="hello";

        Response response = client
                .target(serviceUrl)
                .path(path)
                .request(ExtendedMediaType.APPLICATION_UTF8)
                .get();

        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            return response.getEntity(String.class);
        }

        throw new WebApplicationException(response);
    }
}