How can I debug my retrofit API call?

29,051

Solution 1

Use HttpLoggingInterceptor along with Retrofit.

If this helps, add this inside your build.gradle -

//Retrofit and OkHttp for Networking
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Logging Network Calls
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'

Inside your APIClient class add this -

public class ApiClient {
    private static Retrofit retrofit = null;

    public static Retrofit getClient(){

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();


        if(retrofit==null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(BuildConfig.baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build();
        }
        return retrofit;
    }
}

Kotlin Code

val interceptor : HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }

val client : OkHttpClient = OkHttpClient.Builder().apply {
            addInterceptor(interceptor)
        }.build()


fun getService(): Service {
        return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(LiveDataCallAdapterFactory())
                .client(client)
                .build()
                .create(Service::class.java)
    }

And you will be able to log the Retrofit Network calls that you make.

Let me know if you need more information.

Solution 2

An OkHttp interceptor which logs HTTP request and response data.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BASIC);
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(logging)
    .build();

You can change the log level at any time by calling setLevel.

There are 4 levels: NONE, BASIC, HEADERS, BODY

To log to a custom location, pass a Logger instance to the constructor.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new 
Logger() {
@Override public void log(String message) {
    Log.d(TAG, "message: ");
    }
});

From Gradle

compile 'com.squareup.okhttp3:logging-interceptor:(insert latest version)'

Follow this reference

EDITED: I also found this library which has a very nice structure and clean log. Try it!!

Solution 3

You can use the following class to log API calls

import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor

object HTTPLogger {
    fun getLogger(): OkHttpClient {
        /*
         * OKHTTP interceptor to log all API calls
         */
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build()
        return client
    }
}

You can then call this class in your retrofit instance class like this

import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitClientInstance {
    private var retrofit: Retrofit? = null
    val retrofitInstance: Retrofit?
        get() {
            if (retrofit == null) {
                retrofit = Retrofit.Builder()
                        .baseUrl(Constants.BASE_URL)
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(HTTPLogger.getLogger())
                        .build()
            }
            return retrofit
        }
}

The dependency required is

implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
Share:
29,051
intA
Author by

intA

Updated on August 24, 2021

Comments

  • intA
    intA over 2 years

    I'm using retrofit to get some data from the Flickr api. The method I'm making the call in looks like this:

    public static List<String> getImageIds(int size) {
        Call<PhotosList> call = flickrService.getPhotos(apiKey, format, "1");
        Log.d("TEMP_TAG", "photo url: " + call.request().url().toString());
        photoIds = new ArrayList<String>();
    
        call.enqueue(new Callback<PhotosList>(){
            @Override
            public void onResponse(Call<PhotosList> call, Response<PhotosList> response) {
                Log.d("TEMP_TAG", "it's getting here");
                PhotosList photosList = response.body();
                List<Photo> photos = photosList.getPhotos().getPhoto();
    
                for(Photo photo : photos) {
                    Log.d("TEMP_TAG", "adding photo id to list: " + photo.getId());
                    photoIds.add(photo.getId());
                }
            }
    
            @Override
            public void onFailure(Call<PhotosList> call, Throwable t) {
                // TODO: Clean up
                Log.d("TEMP_TAG", "photoId: ");
            }
        });
        Log.d("TEMP_TAG", "it's getting here too");
        return photoIds;
    }
    

    However it is never getting into the onResponse() method. The first log statement within onResponse() never prints, neither does the log statement in onFailure(). When I try entering the URL that is returned by call.request().url().toString() in the browser it works fine, and I get the expected JSON. Why is my enqueue() method never firing?

    Thanks for any help!

  • intA
    intA over 6 years
    Hmm, this doesn't seem to be doing anything for me. Used the above code and put the HttpLoggingInterceptor in the method making the calls, but nothing gets output.
  • nhp
    nhp over 6 years
    Did you add client for retrofit by using this Retrofit#client(client)?
  • intA
    intA over 6 years
    Yes, I did add the .client(client) to the chain where I am building my Retrofit object
  • nhp
    nhp over 6 years
    Because OkHttp is designed at Builder pattern, so carefully implement OkHttp with HttpLoggingInterceptor before call .build()
  • TooManyEduardos
    TooManyEduardos over 6 years
    You may want to add the code of how you're initializing Retrofit, Gson, and any adapter
  • Leon
    Leon over 5 years
    using java8: HttpLoggingInterceptor logging = new HttpLoggingInterceptor((msg)-> { System.out.println(msg); });
  • android developer
    android developer about 3 years
    That's just logging. What about actual debugging? One with breakpoints? For some reason, getting the response-body's fields stays on "collecting data..." forever. See here: i.imgur.com/SCEL7K2.png . How could it be? What can I do to make it have the value ?
  • hsm59
    hsm59 over 2 years
    Based on the screenshot, the response.body() already shows the errorCode value to be 0, moreover, you can use evaluate expression to run a particular command in debug mode. You can learn more about Evaluate Expression from here