New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle Empty Body #1554

Closed
roybrener opened this Issue Feb 1, 2016 · 32 comments

Comments

@roybrener

roybrener commented Feb 1, 2016

After updating to retrofit beta-3 I'm getting the Exception (Because of an empty body)

java.io.EOFException: End of input at line 1 column 1
                                                                           at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1414)
                                                                           at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:553)
                                                                           at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
                                                                           at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:202)
                                                                           at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:260)
                                                                           at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:33)
                                                                           at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:23)
                                                                           at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:154)
                                                                           at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:92)
                                                                           at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)

I know that It's possible to solve this issue Using Call<Void> but is there any other way to enforce OkHttp or Gson To accept Empty body?

Response Log:

 D/OkHttp: Date: Mon, 01 Feb 2016 08:32:10 GMT
D/OkHttp: Server: Apache/2.4.7 (Ubuntu)
D/OkHttp: X-Powered-By: PHP/5.5.9-1ubuntu4.13
D/OkHttp: Expires: Thu, 19 Nov 1981 08:52:00 GMT
D/OkHttp: Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
D/OkHttp: Pragma: no-cache
D/OkHttp: Access-Control-Allow-Origin: https://example.com
D/OkHttp: Access-Control-Allow-Methods: GET,POST,OPTIONS
D/OkHttp: Access-Control-Allow-Headers: Accept,Cache-Control,Pragma,Origin,Authorization,Content-Type,X-Requested-With,Cookie,*
D/OkHttp: Access-Control-Allow-Credentials: true
D/OkHttp: Content-Length: 0
D/OkHttp: Keep-Alive: timeout=5, max=99
D/OkHttp: Connection: Keep-Alive
D/OkHttp: Content-Type: application/json
D/OkHttp: OkHttp-Sent-Millis: 1454315528548
D/OkHttp: OkHttp-Received-Millis: 1454315528725
D/OkHttp: <-- END HTTP (0-byte body)
@FabianTerhorst

This comment has been minimized.

FabianTerhorst commented Feb 1, 2016

Are you getting the same error when you don´t set a converter factory?

@roybrener

This comment has been minimized.

roybrener commented Feb 1, 2016

I didn't test without the converter. I guess it will not fail because GsonResponseBodyConverter.convert will not run. Is there any reason why i should check without the converter?

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Feb 1, 2016

What behavior do you expect when the body is empty then?

You are telling Retrofit to deserialize the response as a certain object and Retrofit tells Gson to parse the stream into that type and the type is empty. This behavior already seems very reasonable to me.

@roybrener

This comment has been minimized.

roybrener commented Feb 2, 2016

Just return an "empty" pojo response (Like it was until now)... all fields null? It's a real problem...for example I didn't write the server side, just the Android App...The server side returns 200 with empty body...but there are times that the same call will return a 200 with a body message. I have nothing to do in situations like that

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Feb 2, 2016

An empty pojo is {} in JSON.

You can write a delegating converter that does this, the behavior will not be added to Retrofit by default.

class NullOnEmptyConverterFactory implements Converter.Factory {
  @Override public Converter<ResponseBody, ?> responseBody(Type type, Annotation[] annotations, Retrofit retrofit) {
    final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
    return new Converter<>() {
      @Override public void convert(ResponseBody body) {
        if (body.contentLength() == 0) return null;
        return delegate.convert(body);
      }
    };
  }
}
Retrofit retrofit = new Retrofit.Builder()
    .endpoint(..)
    .addConverterFactory(new NullOnEmptyConverterFactory())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
@TheHal85

This comment has been minimized.

TheHal85 commented Apr 21, 2016

I had to implement this for a requirement from my services team. Here is the updated code I used for release version of Retrofit 2.0 that seems to be working in case anyone else comes across the issue.

public class NullOnEmptyConverterFactory extends Converter.Factory {

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
            return new Converter<ResponseBody, Object>() {
                @Override
                public Object convert(ResponseBody body) throws IOException {
                    if (body.contentLength() == 0) return null;
                    return delegate.convert(body);                }
            };
    }
}
@nAkhmedov

This comment has been minimized.

nAkhmedov commented May 12, 2016

body.contentLength() always returns -1 on me. What to do?

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented May 12, 2016

Just read it. That means unknown content length.

On Wed, May 11, 2016, 11:51 PM nAkhmedov notifications@github.com wrote:

body.contentLength() always returns -1 on me. What to do?


You are receiving this because you modified the open/close state.

Reply to this email directly or view it on GitHub
#1554 (comment)

@nAkhmedov

This comment has been minimized.

nAkhmedov commented May 12, 2016

05-12 11:57:35.040 12039-13092/com.sms.sendsms D/OkHttp: <-- 200 OK http://www.yesplease.co.il/app/login.asp?username=zolim2&password=123456g (554ms)
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Cache-Control: must-revalidate,no-cache,private
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Content-Type: text/html; Charset=utf-8
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Expires: Wed, 11 May 2016 06:58:56 GMT
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Vary: Accept-Encoding
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Server: Microsoft-IIS/7.5
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: X-Powered-By: Yes Please
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Server: Server
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Date: Thu, 12 May 2016 06:58:56 GMT
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Connection: Keep-Alive
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Set-Cookie: source=; path=/
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: Set-Cookie: ASPSESSIONIDCSASTAQA=NCLNDGIBMFFIEGMOBHIABCEC; path=/
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: OkHttp-Sent-Millis: 1463036254545
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: OkHttp-Received-Millis: 1463036255040
05-12 11:57:35.041 12039-13092/com.sms.sendsms D/OkHttp: <-- END HTTP (0-byte body)
05-12 11:57:35.081 12039-12039/com.sms.sendsms W/System.err: java.io.EOFException: End of input at line 1 column 1

@nAkhmedov

This comment has been minimized.

nAkhmedov commented May 12, 2016

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();//If need to logging, just uncomment
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ContextConstants.APP_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();

@AllenVork

This comment has been minimized.

AllenVork commented Jul 19, 2016

I add the NullOnEmptyConverterFactory to the retrofit, and still gets the error.Then I find the order is important.

Retrofit retrofit = new Retrofit.Builder()
    .endpoint(..)
    .addConverterFactory(new NullOnEmptyConverterFactory()) //this should come first
    .addConverterFactory(GsonConverterFactory.create())
    .build();
@jacklt

This comment has been minimized.

jacklt commented Jul 29, 2016

help for Kotlin devs

val nullOnEmptyConverterFactory = object : Converter.Factory() {
    fun converterFactory() = this
    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit) = object : Converter<ResponseBody, Any?> {
        val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
        override fun convert(value: ResponseBody) = if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null
    }
}
@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Aug 12, 2016

@jacklt That is an inefficient solution. You have to look up the converter for every response. Look it up once in the factory so that it can be used over and over by the returned converter.

@jacklt

This comment has been minimized.

jacklt commented Aug 12, 2016

@JakeWharton Why? I create only one Converter.Factory(). What's wrong with that code?

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Aug 12, 2016

It calls nextResponseBodyConverter for every response.

@NightlyNexus

This comment has been minimized.

Contributor

NightlyNexus commented Aug 12, 2016

@jacklt You want to cache the result of nextResponseBodyConverter.
something like:

override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? {
  val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any>(this, type, annotations)
  return Converter<ResponseBody, Any> {
    if (it.contentLength() != 0L) {
      nextResponseBodyConverter.convert(it)
    } else {
      null
    }
  }
}
@jacklt

This comment has been minimized.

jacklt commented Aug 12, 2016

Ok, thanks! That's the full version

val nullOnEmptyConverterFactory = object : Converter.Factory() {
    fun converterFactory() = this
    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit) = object : Converter<ResponseBody, Any?> {
        val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
        override fun convert(value: ResponseBody) = if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null
    }
}
@Piasy

This comment has been minimized.

Piasy commented Aug 21, 2016

In Gson's fromJson implementation, it take care of empty JSON string, by catching the EOFException and returning null, its comment said:

For compatibility with JSON 1.5 and earlier, we return null for empty documents instead of throwing.

So could it be possible that GsonResponseBodyConverter apply the same logic?

Any way, the NullOnEmptyConverterFactory is a good solution.

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Aug 21, 2016

No, we won't be implementing that. An empty body is not valid JSON.

On Sun, Aug 21, 2016 at 12:58 AM Piasy notifications@github.com wrote:

In Gson's fromJson implementation
https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/Gson.java#L891,
it take care of empty JSON string, by catching the EOFException and
returning null, its comment said:

For compatibility with JSON 1.5 and earlier, we return null for empty
documents instead of throwing.

So could it be possible that GsonResponseBodyConverter apply the same
logic?

Any way, the NullOnEmptyConverterFactory is a good solution.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#1554 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEEEYMo8CG1Ae36ntGwnUxno5Gc4vISks5qh9sOgaJpZM4HQXza
.

@SaadBilal

This comment has been minimized.

SaadBilal commented Aug 26, 2016

@JakeWharton will it deal with empty arrays like "array":[] ?

@JakeWharton

This comment has been minimized.

Collaborator

JakeWharton commented Aug 26, 2016

That's up to the serialization library you are using.

@Piasy

This comment has been minimized.

Piasy commented Sep 4, 2016

I've got a good way to handle this, just want to share with you guys :)

I create an EmptyJsonLenientConverterFactory to deal with empty body:

public class EmptyJsonLenientConverterFactory extends Converter.Factory {

    private final GsonConverterFactory mGsonConverterFactory;

    public EmptyJsonLenientConverterFactory(GsonConverterFactory gsonConverterFactory) {
        mGsonConverterFactory = gsonConverterFactory;
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
            Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return mGsonConverterFactory.requestBodyConverter(type, parameterAnnotations,
                methodAnnotations, retrofit);
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
            Retrofit retrofit) {
        final Converter<ResponseBody, ?> delegateConverter =
                mGsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
        return value -> {
            try {
                return delegateConverter.convert(value);
            } catch (EOFException e) {
                // just return null
                return null;
            }
        };
    }
}

And besides, my server return api error in HTTP 200 response, so I also create a YLApiErrorAwareConverterFactory to catch them:

public class YLApiErrorAwareConverterFactory extends Converter.Factory {

    private final EmptyJsonLenientConverterFactory mEmptyJsonLenientConverterFactory;

    public YLApiErrorAwareConverterFactory(
            EmptyJsonLenientConverterFactory emptyJsonLenientConverterFactory) {
        mEmptyJsonLenientConverterFactory = emptyJsonLenientConverterFactory;
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
            Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return mEmptyJsonLenientConverterFactory.requestBodyConverter(type, parameterAnnotations,
                methodAnnotations, retrofit);
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
            Retrofit retrofit) {
        final Converter<ResponseBody, ?> apiErrorConverter =
                mEmptyJsonLenientConverterFactory.responseBodyConverter(YLApiError.class,
                        annotations, retrofit);
        final Converter<ResponseBody, ?> delegateConverter =
                mEmptyJsonLenientConverterFactory.responseBodyConverter(type, annotations,
                        retrofit);
        return value -> {
            // read them all, then create a new ResponseBody for ApiError
            // because the response body is wrapped, we can't clone the ResponseBody correctly
            MediaType mediaType = value.contentType();
            String stringBody = value.string();
            try {
                Object apiError = apiErrorConverter
                        .convert(ResponseBody.create(mediaType, stringBody));
                if (apiError instanceof YLApiError && ((YLApiError) apiError).isApiError()) {
                    throw (YLApiError) apiError;
                }
            } catch (JsonSyntaxException notApiError) {
            }
            // then create a new ResponseBody for normal body
            return delegateConverter.convert(ResponseBody.create(mediaType, stringBody));
        };
    }
}

And to wire them up:

Retrofit retrofit = new Retrofit.Builder().client(okHttpClient)
        .baseUrl(URL)
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .addConverterFactory(new YLApiErrorAwareConverterFactory(
                new EmptyJsonLenientConverterFactory(GsonConverterFactory.create(gson))))
        .build();
@GJson

This comment has been minimized.

GJson commented Oct 17, 2016

package com.dooioo.core.network;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**

  • Created by gjson on 2016/10/17.

  • Name NullOnEmptyConverterFactory

  • Version 1.0
    */
    public class NullOnEmptyConverterFactory extends Converter.Factory {

    @override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);

    return new Converter<ResponseBody, Object>() {
    
        @Override
        public Object convert(ResponseBody value) throws IOException {
    
            if (value.contentLength() == 0) return null;
            return delegate.convert(value);
        }
    };
    

    }
    }

@Ztiany

This comment has been minimized.

Ztiany commented Oct 17, 2016

  //ConverterFactory
  @Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
                                                        Annotation[] annotations,
                                                        Retrofit retrofit) {
    final Converter<ResponseBody, ?> delegateConverter =        // 3
            mGsonConverterFactory.responseBodyConverter(type,
                    annotations, retrofit);

    return new Converter<ResponseBody, Object>() {
        @Override
        public Object convert(ResponseBody value) throws IOException {
            try {
                return delegateConverter.convert(value);            // 4
            } catch (JsonSyntaxException e) {
                // just return null
                Timber.e("Json covert error -->error : " + e);
                return ApiHelper.createErrorResult();     // return a errorResult
            }
        }
    };
}
      //crate errorResult
       public static HttpResult createErrorResult() {
             HttpResult httpResult = new HttpResult();
             httpResult.setCode(DATA_ERROR);
            return httpResult;
      }


      //hand error
      @Override
      public Observable<R> call(HttpResult<R> rHttpResult) {
          if (rHttpResult == null) {

               return Observable.error(new NetworkConnectionException());

             } else if (ApiHelper.isDataError(rHttpResult)) {

                 return Observable.error(new ServerErrorException());//server data error

             } else if (!ApiHelper.isSuccess(rHttpResult)) {

                 if (ApiHelper.isLoginExpired(rHttpResult)) {
                     RxBus.send(new EventLoginExpired());
                 }
                 return Observable.error(createException(rHttpResult));

             } else {
                 return Observable.just(rHttpResult.getData());
             }
         }
@grennis

This comment has been minimized.

grennis commented Dec 13, 2016

The server I am talking to (which I do not control) does not return a valid content-length so solutions that rely on it do not work for me. Furthermore I am using kotlin and using moshi. This is the only solution I could get working. I realize this has a serious error that swallows EOFException but I do not see any other way of doing this. Any ideas?

class NullMoshiConverterFactory(val moshi: Moshi) : Converter.Factory() {
    val factory: MoshiConverterFactory

    init {
        factory = MoshiConverterFactory.create(moshi)
    }

    override fun requestBodyConverter(type: Type?, parameterAnnotations: Array<out Annotation>?, methodAnnotations: Array<out Annotation>?, retrofit: Retrofit?): Converter<*, RequestBody> {
        return factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit)
    }

    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? {
        return NullConverterFactory(factory.responseBodyConverter(type, annotations, retrofit))
    }

    class NullConverterFactory(val wrapped: Converter<ResponseBody, *>) : Converter<ResponseBody, Any> {
        override fun convert(value: ResponseBody?): Any? {
            try {
                return wrapped.convert(value)
            } catch (ex: EOFException) {
                return null
            }
        }
    }
}
@trinadhkoya

This comment has been minimized.

trinadhkoya commented Apr 28, 2017

E/UncaughtException: java.lang.IllegalArgumentException: Expected receiver of type com.XXXX.models.SuccessResponse, but got retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall

@kelvindu kelvindu referenced this issue May 18, 2017

Closed

Empty Json Body #1

@SugerQ

This comment has been minimized.

SugerQ commented Aug 8, 2017

@nAkhmedov I met the same situation as you, how do you deal with it?

@nAkhmedov

This comment has been minimized.

nAkhmedov commented Aug 8, 2017

@SugerQ i tottaly forget what was the reason. Sorry

@paulpv

This comment has been minimized.

paulpv commented Oct 25, 2017

Blast from the past, but here is a fully anonymous impl:

Retrofit retrofit = new Retrofit.Builder()
...
//
// Prevent empty body from throwing "java.io.EOFException: End of input at line 1 column 1 path $"
// Per: https://github.com/square/retrofit/issues/1554
//
.addConverterFactory(new Factory()
{
    @Nullable
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit)
    {
        final Converter<ResponseBody, Object> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
        return new Converter<ResponseBody, Object>()
        {
            @Override
            public Object convert(@NonNull ResponseBody body)
                    throws IOException
            {
                return body.contentLength() != 0 ? delegate.convert(body) : null;
            }
        };
    }
})
...
.build();        
@kcorey

This comment has been minimized.

kcorey commented Nov 30, 2017

Sadly, here's another 'me too'.

I've tried each and every one of these approaches, without success.

I'm creating my builder like this:

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url.toString())
                .client(client)
                .addConverterFactory(new NullOnEmptyConverterFactory())
                .addConverterFactory(converterFactory)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

This is in a static method, so I'm creating my NullConverter like this:

    public static class NullOnEmptyConverterFactory extends Converter.Factory {
        @Override
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
            final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
            Log.d(TAG, "responseBodyConverter: creating the NULL converter");
            return new Converter<ResponseBody, Object>() {
                @Override
                public Object convert(ResponseBody body) throws IOException {
                    Log.d(TAG, "convert: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                    if (body.contentLength() == 0) {
                        Log.d(TAG, "convert: returning null");
                        return null;
                    } else {
                        Log.d(TAG, "convert: returning the delegate.convert result");
                        return delegate.convert(body);
                    }
                }
            };
        }
    }

Now, in every call where there's a body, I'm getting this in the log:

convert: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
convert: returning the delegate.convert result

So, it would seem as if the Null Converter is at least trying to do its job.

However, on the call that is causing me difficulties (200 response, but empty body), I don't get those lines in the output.

All I can imagine is that the EOFException is being generated before the converter is getting a chance to protect us from the EOFException. So, even though I'm getting a 200 from the server, my code is in the error handler branch.

Yes, for pedants, I understand this is not "good", "valid" or "proper" HTML, and that the server needs to change. To that I would say that the world is not perfect. It shouldn't be so ridiculously hard to handle such a simple situation.

-Ken

@Shubhampatni86

This comment has been minimized.

Shubhampatni86 commented Feb 13, 2018

In my case I'm receiving Response body "[text={"errorCode":"username_in_use","messages":null}]" but still while converting response it throwing EOFException. Any suggestion !!

converter.convert(responseBody)

@jayeshpansheriya

This comment has been minimized.

jayeshpansheriya commented Oct 27, 2018

hello guys i face same error in retrofit with kotlin please suggest me
use below link to see my code and give me suggestion


https://stackoverflow.com/questions/52946537

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment