Hamza Sharaf
Hamza Sharaf

Reputation: 871

Catching an error message with retrofit HttpException

I'm using Retrofit to make some requests to the API, and when I receive back the response it's usually received from the API in this format if the request is successful

Successful Response

{
    "success": 1,
    "error": [],
    "data": [
        // Some data..
     ]
}

And if there is an error, the response will go like this

Unsuccessful Response

{
    "success": 0,
    "error": [
        "Password is incorrect"
    ],
    "data": []
}

The problem now in case there is an unsuccessful request, it comes with error code 403, so Retrofit classifies it as an Exception and throws an HttpException, then i have no way to catch the password is incorrect message attached in the json response.

Is there any way I still can get the body response even if there is an HttpException?

Update

This is the sample code I'm using

ViewModel

viewModelScope.launch {
    try {
        val result = myApi.request(requestParam)
    }catch (e: HttpException){
        // Log the error
    }
}

Upvotes: 5

Views: 4965

Answers (2)

rufeng
rufeng

Reputation: 121

You can add an extension method like this:

inline fun Job.onHttpError(crossinline block: (HttpException) -> Unit) {
 this. invokeOnCompletion {
     if (it != null && it is HttpException) block(it)
 }
}

Then you can get the exception information like this:

viewModelScope.launch {
  val result = global.apiService.legalDigitalList()
}.onHttpError {
  showLog(it. message)
}

Upvotes: 0

Hamza Sharaf
Hamza Sharaf

Reputation: 871

Well, I figured out a way to get back the response from the passed exception.

As I said in the question, this is the code I'm using

Old code sample

viewModelScope.launch {
    try {
        val result = myApi.request(requestParam)
    }catch (e: HttpException){
        // Log the error
    }
}

However, I didn't know that the response body is passed with the exception, and you can receive it as a string using the errorBody() method as follows.

New code sample

viewModelScope.launch {
    try {
        val result = myApi.request(requestParam)
    }catch (e: HttpException){
        val response = e.response()?.errorBody()?.string()
    }
}

And from there you can manipulate this string to extract the error message.

Upvotes: 4

Related Questions