How to handle errors and exceptions using Retrofit in Kotlin Android
How to handle errors and exceptions using Retrofit in Kotlin Android.
Here's a step-by-step tutorial on how to handle errors and exceptions using Retrofit in Kotlin for Android:
Step 1: Set up Retrofit
First, make sure you have Retrofit added to your Android project. You can add it to your build.gradle
file by including the following dependency:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Also, don't forget to add the Internet permission to your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET" />
Step 2: Create a Retrofit instance
Next, create a Retrofit instance in your application code. This instance will be used to make network requests and handle responses. Here's an example:
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
Make sure to replace "https://api.example.com/"
with the base URL of your API.
Step 3: Define API interface
Create an interface that defines your API endpoints. Each method in the interface represents a different API request. Here's an example:
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): Response<User>
}
Note the use of the suspend
keyword, which allows you to use coroutines for asynchronous programming.
Step 4: Handle errors and exceptions
To handle errors and exceptions in Retrofit, you can use the Response
object returned by the API methods. The Response
object contains information about the HTTP response, including the status code and the response body.
Here's an example of how you can handle different scenarios:
val apiService = retrofit.create(ApiService::class.java)
try {
val response = apiService.getUser(userId)
if (response.isSuccessful) {
// Successful response
val user = response.body()
// Do something with the user object
} else {
// Error response
val errorBody = response.errorBody()?.string()
// Handle the error response
}
} catch (e: IOException) {
// Network error
// Handle the network error
} catch (e: Exception) {
// Other exceptions
// Handle other exceptions
}
In the above example, if the API request is successful (response.isSuccessful
), you can access the response body using response.body()
. If there's an error, you can get the error response body using response.errorBody()?.string()
.
You can also catch specific types of exceptions to handle different scenarios. For example, catching IOException
allows you to handle network errors specifically.
Step 5: Custom error handling
If you want to handle errors in a more structured way, you can create custom error classes and use Retrofit's error converter. Here's an example:
data class ErrorResponse(val code: Int, val message: String)
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ErrorConverterFactory())
.build()
class ErrorConverterFactory : Converter.Factory() {
override fun responseBodyConverter(
type: Type,
annotations: Array<Annotation>,
retrofit: Retrofit
): Converter<ResponseBody, *>? {
val gson = Gson()
val adapter = gson.getAdapter(ErrorResponse::class.java)
return ErrorResponseBodyConverter(gson, adapter)
}
}
class ErrorResponseBodyConverter<T>(
private val gson: Gson,
private val adapter: TypeAdapter<T>
) : Converter<ResponseBody, T> {
override fun convert(value: ResponseBody): T? {
val errorBody = value.string()
val errorResponse = gson.fromJson(errorBody, ErrorResponse::class.java)
throw ApiException(errorResponse.code, errorResponse.message)
}
}
class ApiException(val code: Int, message: String) : RuntimeException(message)
In this example, we create an ErrorResponse
class to represent the error response from the API. We also create a custom Converter.Factory
to handle the conversion of error responses. The ErrorResponseBodyConverter
class converts the response body into an ErrorResponse
object and throws an ApiException
with the error code and message.
To use this custom error handling, include the ErrorConverterFactory
in your Retrofit instance.
That's it! You now know how to handle errors and exceptions using Retrofit in Kotlin for Android.