AnZ AnZ - 2 months ago 54
Android Question

Retrofit 2 - string error body is empty

Server returns

object in case of success and simple
for error case.

There are no problems with parsing
into object. The problem rises when I want to parse error since the
is empty.

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

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

Code code


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'

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

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

Retrofit client = new Retrofit.Builder()
gitApiInterface = client.create(GitApiInterface.class);
return gitApiInterface;

public interface ApiInterface {

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);

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) {

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

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

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

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

public void onFailure(Call<User> call, Throwable t) {



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 {

public String message;

public ArrayList<ErrorDetail> errors;