0

I want to log the error message when the API call returns bad request or status code = 400

I am doing this

call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            if(response.isSuccessful()){
                Log.e(TAG, "onResponse: "+response.message() );
                Toast.makeText(RegisterCanister.this, "Registered Successfully!", Toast.LENGTH_SHORT).show();
            }
            else {
                    try {
                    Log.e(TAG, "onResponse: "+response.errorBody().string() );
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
        }

        @Override
        public void onFailure(Call call, Throwable t) {
            Toast.makeText(RegisterCanister.this, "Inhaler Registration Failed", Toast.LENGTH_SHORT).show();
        }
    });

The above code gets into the else condition as the response code is 400 where the response.errorBody is not null but I am not able to get the response of it. I tried using a converter and also JSONObject, faced the same issue. Wasn't able to extract the info from the errorBody()

Log.e(TAG, "onResponse: "+response.errorBody().string() );

logs

E/RegisterCanister: onResponse:

but

Log.e(TAG, "onResponse: "+response.errorBody());

logs

E/RegisterCanister: onResponse: okhttp3.ResponseBody$1@a33dda6

my error response is like this when trying in postman.

{"error":"Device not found"}
Sourav Singh
  • 85
  • 1
  • 1
  • 12

3 Answers3

0

Error code should be catch with your response object, for example (on Kotlin, but you can easily translate into Java) :

            when {
                response?.code() == 200 -> // Success
                    callback.onResponse(response.body())
                response?.code() != 200 -> // Error
                    callback.onError(ON_FAILURE)
            }

Instead of using errorBody for this purpose.

Otherwise, you can try to create a custom Callback interface :

interface YourCallback {
    fun onResponse(model: YourModel)
    fun onError(message: String)
}

Then, use this interface :

override fun getYourData(query: YourCall ,callback: YourCallback) {
        aCall?.yourNeed?.enqueue(object : Callback<YourModel> {
            /** Handle responses */
            override fun onResponse(call: Call<YourModel>?, response: Response<YourModel>?) {
                when {
                    response?.code() == 200 -> // Success
                        callback.onResponse(response.body())
                    response?.code() != 200 -> // Error
                        callback.onError(ON_FAILURE)
                }
            }

            /** Handle failure */
            override fun onFailure(call: Call<YourModel>?, t: Throwable?) {
                callback.onError(t?.message ?: ON_FAILURE)
            }
        })
    }

Hope it can fits your needs :) Good luck.

Neandril
  • 122
  • 9
0

@SouravSingh First check what you get in answer of your responce.body().string(), by Log after this you will know what you get in answer. The another way is check how look full post open Logcat in Verbose and find Post here you will see all data about connection.

0

The solution is using the code response.errorBody().string() only once. Retrofit / OkHttp3 400 Error Body Empty.

flame3
  • 2,812
  • 1
  • 24
  • 32
  • If you need to use response.errorBody().string() more than once, check this answer out: https://stackoverflow.com/a/73857446/9952567 – Vladimir Kattsyn Sep 26 '22 at 17:06