4

I am trying to get the error returned by a service (when starting with invalid credentials) rest api but for some reason errorBody does not catch it from my answer.

The correct answer I receive without problems but when I get an error I can't solve what the server sends me.

Sorry for my English, I had to use the translator

This is the part where I should get the error

override fun postLogin(callback: OperationCallBack<ResponseToken>, user: Login) {
    call = Api.build()?.login(user)
    call?.enqueue(object :Callback<ResponseToken>{
        override fun onFailure(call: Call<ResponseToken>, t: Throwable) {
            callback.onError(t.message)
        }

        override fun onResponse(call: Call<ResponseToken>, response: Response<ResponseToken>) {
            Log.v(TAG, "ErrorMensaje: ${response.message()}")
            Log.v(TAG, "ErrorBodyToString: ${response.errorBody().toString()}")

            response.body()?.let {
                if(response.isSuccessful && (it.isSuccess())){
                    Log.v(TAG, "token ${it.token}")
                    callback.onSuccess(it)
                }else{
                    Log.v(TAG, "token ${it.token}")
                    callback.onError("Error ocurrido")
                }
            }
        }
    })
}

errorBody shows me only with toString otherwise it returns null. With toString this is what I get

2020-06-10 19:26:05.095 26590-26590/com.umbani.umbani V/CONSOLE: ErrorMensaje:
2020-06-10 19:26:05.095 26590-26590/com.umbani.umbani V/CONSOLE: ErrorBodyToString: okhttp3.ResponseBody$Companion$asResponseBody$1@fcb3843

The okHttp console shows the error as it comes from the server, which I cannot catch

D/OkHttp: {"success":true,"error":{"message":"Invalid credentials"}}

It is not a problem to convert with Gson or another converter. I can do that. I have done so with the positive response.

I have seen many answers on StackOverFlow and none has helped me. Thank you

UPDATE: I found the solution in this answer: https://stackoverflow.com/a/55835083/10372439

SOLUTION:

Replace toString () to string ()

response.errorBody()!!.string()
  • saved my day for telling just ."string()". for those who wants to know , when you're received 404 or 400 error code , you should use errorBody() not body(). – NimaAzhd Jun 10 '21 at 07:27

1 Answers1

1

Try overriding the onFailure block, then cast it with the right object

override fun onFailure(call: Call< ResponseToken >, t: Throwable) {
         if (t is HttpException) {
            try {
                val errorStringRaw: String? = t.response()?.errorBody()?.string()
                //Parse error message; format is api specific; we can't make a generic approach for this as of the moment
                val type = object : TypeToken<ResponseBody?>() {}.type
                val response: ResponseBody = Gson().fromJson(errorStringRaw, type)
                } catch (e: Exception) {

                }
         }
}
steven0529
  • 1,513
  • 1
  • 18
  • 28
  • Thanks but it still doesn't work, in fact I have put a Log inside the onFailure and it doesn't enter the method @steven0529 – Salva Valladares Jun 11 '20 at 02:15
  • Check the status code response. Maybe it sends you a STATUS 200 thus Retrofit considers it to be a successful response – steven0529 Jun 11 '20 at 02:21
  • May be try moving the parsing logic from this answer just after `Log.v(TAG, "ErrorBodyToString: ${response.errorBody().toString()}")` for testing purpose. – Smile Jun 11 '20 at 04:34
  • Thank you. That is what I do but printing errorBody.toString() does not return the message coming from the server. Only what I put above. Is there a clear and orderly way to catch errors with retrofit2 when they are not 200? – Salva Valladares Jun 11 '20 at 15:48