M. Adil
M. Adil

Reputation: 180

Retrofit always calling onFailure even response is 200

I am using Retrofit to call my API. I am very new to Retrofit and this is the reason why I am unable to find this error. I send a request to the API, API response is 200 OK but retrofit calls the onFailure method. My API interface is as follows:

public interface API {

    @FormUrlEncoded
    @POST("login")
    Call<Login> login(@Query("user") String email,@Query("pass") String password, @Field("device key") String deviceKey);

}

and my call is:

loginCall = MyApplication.getInstance().getAPI().login(username,password,deviceKey);
        loginCall.enqueue(new Callback<Login>() {
            @Override
            public void onResponse(Call<Login> call, Response<Login> response) {

                if(response.body() != null)
                {
                    Login login = response.body();
                    Toast.makeText(LoginActivity.this, response.body().toString(), Toast.LENGTH_LONG).show();
                    }
                }

            @Override
            public void onFailure(Call<Login> call, Throwable t) {
                Toast.makeText(LoginActivity.this, "Failsssssssss", Toast.LENGTH_LONG).show();
            }
        });

And my model class is as follows:

public class Login {
    String status;
    String Auth_Token;

    public Login(String status, String auth_Token) {
        this.status = status;
        Auth_Token = auth_Token;
    }
}

As far I understand this issue, there is a problem with my model class. My API returns two responses:

"{"status":"200","Auth_Token":"jhjsfbah71yb121t312hv"}"
"{"status":"500","Response":"Invalid Cardentials"}"

Any help would be appreciated. Thanks in advance.

Upvotes: 10

Views: 9757

Answers (5)

Abinash Gadsara
Abinash Gadsara

Reputation: 41

In my case the error is in the data Model class where the response I was getting from the server mentioned below

public class ResponseModel {
@Expose
@SerializedName("status")
private int status;

@Expose
@SerializedName("message")
private String message;

@Expose
@SerializedName("data")
private DataEntity data;

public Integer getStatus() {
    return status;
}

public void setStatus(Integer status) {
    this.status = status;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public dataEntity getData() {
    return data;
}

public void setData(DataEntity data) {
    this.data = data;
}} 

and the response that I received is the data in string in-spite of object.

{
    "status": 0,
    "message": "Unauthorized user",
    "data": "Not Completed",
}

Upvotes: 0

Jay Dangar
Jay Dangar

Reputation: 3469

Using t.message() inside onFailure() reveals the mismatch in datatypes for json to model class, which causes this problem. just debug it via t.message() and change the datatype as suggested in the message, it will solve the problem.

Upvotes: 5

Tandoh Anthony Nwi-Ackah
Tandoh Anthony Nwi-Ackah

Reputation: 2175

In my case, the problem was caused by print_r($data) from my Api.Removing it solved my problem.

OLD CODE

  public function getNewsApi()
    {
            $data = $this->Db_Model->select_all_data('news');
            print_r($data);
            $response['result'] = isset($data) ? $data : '';
            $response['message'] = 'All data';
            $response['status'] = 'true';
            $response['code'] = '200';

        echo json_encode($response);
    }

NEW CODE

public function getNewsApi()
    {
            $data = $this->Db_Model->select_all_data('news');
            $response['result'] = isset($data) ? $data : '';
            $response['message'] = 'All data';
            $response['status'] = 'true';
            $response['code'] = '200';

        echo json_encode($response);
    }

Hope this helps too.

Upvotes: 0

codingdaddy
codingdaddy

Reputation: 497

I had a similar issue. In my case, the problem was caused by casting the response to JSON format. (The response I was getting was not in JSON format) So to figure out the details, I ResponseBody the following way.

Call<ResponseBody> call = client.callTTS(request);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if(response == null)
        {
            Log.d("MainActivity", "Response is null");
        }else
        {
            Log.d("MainActivity", "Response has contents");
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        Log.d("MainActivity", t.getMessage());
    }
});

Hope this helps someone with the same issues.

Upvotes: 0

Usama
Usama

Reputation: 480

There is a problem with your server response. Retrofit reads HTTP Status, So you have to make sure you sent it from the server. Retrofit is trying to read a response code 200 which is not available probably so it is calling on failure method.

Upvotes: 7

Related Questions