Error handling in Retrofit using NetworkResponseAdapter library
Tags: kotlin, retrofit, errors, tutorial
Published: 2023-08-27 08:41:47

---
title: Error handling in Retrofit using NetworkResponseAdapter library
published: true
date: 2022-01-16 11:00:00 UTC
tags: #kotlin,#retrofit,#errorhandling,#tutorial
canonical_url: https://mariuszsoltysiak.hashnode.dev/error-handling-in-retrofit-using-networkresponseadapter-library
---

Im currently working with my team on a new project. One part of it is a gateway service that distributes calls between microservices and/or merges results. We've been looking for a good solution to properly make requests using coroutines. Another requirement was to handle properly responses from the API and that we wont need to handle manually all common error results or IO exceptions.

After looking for some options we found out Retrofit to be the perfect fit for our purpose. But it wasn't easy to find a proper solution to handle successful and failed responses. Id like to give you a simple example of how to configure Retrofit using the [NetworkResponseAdapter](https://github.com/haroldadmin/NetworkResponseAdapter) library to properly and gracefully handle responses in your code with a simple extension function.

Lets define a simple Retrofit client interface with one method to get a list of categories:

[https://gist.github.com/marrek13/f35fdd24eb18ecee90826f92b76c53da](https://gist.github.com/marrek13/f35fdd24eb18ecee90826f92b76c53da)

The problem with this definition is that when there is an exception we will expose the network exception directly to our application layer. It is not a great solution and its better to throw instead some contextual exception connected with what the client is doing. To achieve this goal we defined our own exception:

[https://gist.github.com/marrek13/e1405c25fe6ee70aa1afa380cbd70004](https://gist.github.com/marrek13/e1405c25fe6ee70aa1afa380cbd70004)

We added one line to the Retrofit builder

```
.addCallAdapterFactory(NetworkResponseAdapterFactory())

```

Then the client was modified to use NetworkResponseAdapter:

[https://gist.github.com/marrek13/fc3cc307bb8441c7e575c789e0b744c7](https://gist.github.com/marrek13/fc3cc307bb8441c7e575c789e0b744c7)

NetworkResponse is a sealed class whose result can be one of the classes below:

- **NetworkResponse.Success** : an object containing the successful result with response data for any 2XX response

- **NetworkResponse.ServerError** : an object which contains the response from the call that resulted in a non-2XX status

- **NetworkResponse.NetworkError** : the result of a request that didn't result in a response

- **NetworkResponse.UnknownError** : the result of a request that resulted in an error different from an IO or Server error

- **NetworkResponse.Error** : object for any other possible response not covered by any of previous cases

As you noticed we need to provide the type arguments for deserialization: first for the Success response and the second for the ServerError response.

To achieve the goal which is easy handling of all exceptions/errors in the same manner we introduced an extension function to the NetworkResponse class:

[https://gist.github.com/marrek13/467be212bd60c38b8883f65cca58b0b9](https://gist.github.com/marrek13/467be212bd60c38b8883f65cca58b0b9)

Having all of this together, we can easily call our API in the service without being worried about leaking the IOExceptions from the Retrofit client:

[https://gist.github.com/marrek13/506fd4ed9d881a9ce9aab15db7a6f83f](https://gist.github.com/marrek13/506fd4ed9d881a9ce9aab15db7a6f83f)

And thats it. Adding the call() to all places where the client is used is the only downside of this solution. But in general, we consider it as the most elegant and easy-to-read and test solution.