Retrofit2 Silently Fails to Send to send Request

345 views Asked by At

I am developing an android client to communicate with a REST server. I have been using Retrofit to do this. Up until this point it has been working fine, but today I implemented a new function to get a list of a users data from the server, and Retrofit is not sending the request. I have tried attaching a debugger, and it seems that the call.enqueue method is not being called, and it seems the execution is for whatever reason stopping on the line above with no error. This is the code that builds and queues the request

public void requestMeasurementData(int userID, int startIndex, int numResults){
    FileAPI service = RetroClient.getApiService();

    RequestBody indexRB = RequestBody.create(MediaType.parse("multipart/form-data"), Integer.toString(startIndex));
    RequestBody numResultsRB = RequestBody.create(MediaType.parse("multipart/form-data"), Integer.toString(numResults));
    MultipartBody.Part indexBody = MultipartBody.Part.createFormData("start_index", null, indexRB);
    MultipartBody.Part numResultsBody = MultipartBody.Part.createFormData("num_results", null, numResultsRB);

    Call<List<Session>> sessionCall = service.getBASMIScores(userID, indexBody, numResultsBody);
    sessionCall.enqueue(new Callback<List<Session>>() {
        @Override
        public void onResponse(Call<List<Session>> call, Response<List<Session>> response) {
            if (response.isSuccessful()){
                dataReceived = true;
                sessions = response.body();
            }
            else {
                errorReceived = true;
            }
        }

        @Override
        public void onFailure(Call<List<Session>> call, Throwable t) {

        }
    });
}

The debugger hit a breakpoint on the call to service.getBASMIScores but did not hit the breakpoint I set on the line below.

This is the code for my retrofit client

private static Retrofit getRetroClient() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    InputStream caFileInputStream = BASMIApplication.getRes().openRawResource(R.raw.mystore);

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(caFileInputStream, BASMIApplication.getRes().getString(R.string.mystore_password).toCharArray());

    OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor)
            .sslSocketFactory(createAdditionalCertsSSLSocketFactory(), new AdditionalKeyStoresTrustManager(keyStore))
            .hostnameVerifier(new NullHostNameVerifier())
            .cookieJar(new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(BASMIApplication.getInstance()))).build();

    return new Retrofit.Builder()
            .baseUrl(ROOT_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

public static FileAPI getApiService() {
    try {
        return getRetroClient().create(FileAPI.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

This is where I declare the Api method

@Multipart
@GET("user/{user-id}/basmi_history")
Call<List<Session>> getBASMIScores(@Path("user-id") int user_id,
                                   @Part MultipartBody.Part startIndex,
                                   @Part MultipartBody.Part numResults);

And finally here is my Session data class, in case it is relevant

public class Session {
private int id;
@SerializedName("user_id")
private int userID;
private String date;
private String time;
private float basmi;


public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}


public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public float getBasmi() {
    return basmi;
}

public void setBasmi(float basmi) {
    this.basmi = basmi;
}

public int getUserID() {
    return userID;
}

public void setUserID(int userID) {
    this.userID = userID;
}
}

This is the same exact structure I have used elsewhere in my application where retrofit works fine. I cant work out what is different in this case. There is no error when it fails, and no retrofit message in the console at all. The client is able to log into the server successfully but then when it reaches this code it silently fails.

Does anyone have ideas as to what could be going wrong here?

1

There are 1 answers

0
Birdfriender On BEST ANSWER

Okay, so after digging deeper into the debugger output I managed to figure out the issue. The problem was with using the @Multipart annotation with a GET request, which does not expect a request body. In order to fix this I replaced the two @Part arguments to my request with @Query elements, which is likely better practise anyway.

I am unsure why this throws an exception but doesn't provide any logging output.