AnZ AnZ - 26 days ago 27
Android Question

Retrofit 2 - string error body is empty

Server returns

JSON
object in case of success and simple
String
for error case.

There are no problems with parsing
JSON
into object. The problem rises when I want to parse error since the
response.errorBody().string()
is empty.

When I send the same request using
Postman
the response as follows:
enter image description here

And I can't read this error... Anyone faced such problem?




Code code

gradle
:

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.okhttp:okhttp:2.6.0'


RestClient.java
:

private static GitApiInterface gitApiInterface;
...
public static GitApiInterface getClient() {
if (gitApiInterface == null) {

OkHttpClient okClient = new OkHttpClient();
okClient.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});


Retrofit client = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();
gitApiInterface = client.create(GitApiInterface.class);
}
return gitApiInterface;
}


ApiInterface.java
:

public interface ApiInterface {

@POST("/register/user/{email}/")
Call<User> postRegisterUser(@Path(value = "email", encoded = true) String email,
@Query("firstname") String firstName,
@Query("lastname") String lastName,
@Query("country") String country,
@Query("phone") String phone,
@Query("deviceid") String deviceId);
...


ServerRequests.java
:

public void registerUser(@NonNull String email,
@NonNull String firstName,
@NonNull String lastName,
@NonNull String country,
@NonNull String phone,
@NonNull String deviceId,
@NonNull final RegisterUserCallback callback) {
showProgressBar();

RestClient.GitApiInterface service = RestClient.getClient();
Call<User> call = service.postRegisterUser(email, firstName, lastName, country, phone, deviceId);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
hideProgressBar();

User user = response.body(); //this works great

if (response.isSuccess()) {
Log.d(TAG, "REGISTER success: " + response.message());
callback.onRegisteredUser(user);

} else {
try {
Log.e(TAG, "REGISTER fail: " + response.errorBody().string()); //empty error body
callback.onRegisterFailed(response.errorBody().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public void onFailure(Call<User> call, Throwable t) {
hideProgressBar();

callback.onRegisterFailed("error");
}
});
}

Answer

My answer is based on HttpLoggingInterceptor class.

I wrote getStatusError() method by given in parameter response.errorBody().

private StatusError getStatusError(ResponseBody responseBody) {
    StatusError statusError = null;

    if (responseBody != null) {
        try {
            BufferedSource source = responseBody.source();

            if (source != null) {
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();

                Charset charset = UTF8;
                MediaType contentType = responseBody.contentType();
                if (contentType != null) {
                    charset = contentType.charset(UTF8);
                }

                String string = buffer.clone().readString(charset);

                if (!TextUtils.isEmpty(string)) {
                    GsonBuilder gsonBuilder = new GsonBuilder();
                    Gson gson = gsonBuilder.create();

                    statusError = gson.fromJson(string, StatusError.class);
                }
            }

        } catch (Exception e) {
            LogUtils.LOGW(TAG, "Impossible to get StatusError stream", e);
        }
    }

    return statusError;
}

StatusError is a POJO class to map (JSON) elements:

public class StatusError {

@SerializedName("message")
public String message;

@SerializedName("errors")
public ArrayList<ErrorDetail> errors;

}
Comments