What's causing HTTP FAILED: java.net.SocketException: Socket closed?

12,090

In my case, what I discovered I was getting was a sudden unexpected unsubscribe() call that was causing the HTTP FAILED: java.net.SocketException: Socket closed error and not invoking any of the onCompleted() onError() or onNext() callbacks - check out the discussion and answer here.

So, to be able to handle that case, just add:

.doOnUnsubscribe(() -> { /*handle logic here*/ })

to your Observable and maybe try to reset some state there, which hopefully would result in a the ability to resume normal activity.

Share:
12,090

Related videos on Youtube

jignesh.world
Author by

jignesh.world

Product minded Software Engineer who focuses on product, their domain and delivers best possible user experience by following industry best practices, architecture, test driven development with CI/CD pipelines Enthusiasm, Devotion to work, Eager & Quick learner Self-motivated and well organised team player Proficient to working with teams on software development life cycle(SDLC) from requirement gathering or planning, defining, designing technical architecture, building or developing, testing, deploying and maintaining applications Well verse with development process/tools like Github Actions, CodeMagic, Fastlane, Jenkins, BuddyBuild, Git workflow, Github workflow, Agile PM tools, Continuous integration and Continuous deployment(CI & CD), Test/Domain driven development with keeping healthy test code coverage, etc.. Currently developing cross platform applications with Flutter(mobile/web/desktop) (Since May 2018) Explored different kinds of architecture on flutter and currently using bloclibrary.dev Proficient to integrate and work with different kind of APIs - REST / GraphQL Backend: REST API development using ExpressJS, PostgREST etc.. Backend: GraphQL API development using Apollo GraphQL server, Hasura(similar to PostGraphile) etc.. Proficient to work with relational databases(MySQL/PostgreSQL) and SQL queries Developed many applications using Firebase Cloud Products (BaaS). Worked on many different user-friendly, aesthetically pleasing and fully functional applications Proficient in object-oriented design, data structures, problem solving, complexity analysis, and debugging Proficient in writing efficient, maintainable, reusable, testable code that preserves privacy and security Proficient to work with many programming languages like Dart, Java, Kotlin, Swift, JavaScript, TypeScript, NodeJS, Python etc.. Regular follower of news, groups, communities, forums and blogs to stay connected and updated Trying to contribute something back to the community by providing mentorship, write articles and creating video tutorials Trained/Mentored and motivated mobile team members(Flutter + Android + iOS)

Updated on June 04, 2022

Comments

  • jignesh.world
    jignesh.world almost 2 years

    I am using okhttp and retrofit for one of my application and I have many request working on different threads using RxJava. Sometimes I got SocketException on any of the request and afterwords no request can reach at server.

    For e.g. I can share one sample.

    Few modified snippet from code I can share.

    Subscription details = api.details("keyword")
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<Model>() {
                        @Override
                        public void onCompleted() {
                            Timber.d("onCompleted(): ");
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Timber.e(e, "onError(): ");
                        }
    
                        @Override
                        public void onNext(final Model details) {
                            Timber.d("onNext(): ");
                        }
                    });
    

    Nothing called from all of 3 callbacks.

    Stackstace :

    11-17 15:50:53.991 16595-10314/ D/OkHttp: --> GET API_REQUEST_URL
    11-17 15:50:53.991 16595-10314/ D/OkHttp: Host: HOST_NAME
    11-17 15:50:53.991 16595-10314/ D/OkHttp: Connection: Keep-Alive
    11-17 15:50:53.991 16595-10314/ D/OkHttp: Accept-Encoding: gzip
    11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: okhttp/3.4.2
    11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: Android-App
    11-17 15:50:53.991 16595-10314/ D/OkHttp: --> END GET
    11-17 15:50:53.992 16595-10314/ D/OkHttp: <-- HTTP FAILED: java.net.SocketException: Socket closed
    

    Other IOException

    11-17 16:36:04.274 28523-29137/ D/OkHttp: Host: HOST_NAME
    11-17 16:36:04.274 28523-29137/ D/OkHttp: Connection: Keep-Alive
    11-17 16:36:04.274 28523-29137/ D/OkHttp: Accept-Encoding: gzip
    11-17 16:36:04.274 28523-29137/ D/OkHttp: User-Agent: okhttp/3.4.2
    11-17 16:36:04.274 28523-29137/ D/OkHttp: User-Agent: Android-App
    11-17 16:36:04.274 28523-29137/ D/OkHttp: --> END GET
    11-17 16:36:04.282 28523-29137/ D/OkHttp: <-- HTTP FAILED: java.io.IOException: unexpected end of stream on okhttp3.Address@6924d4a0
    

    Subscription I am trying to call frequently working fine but sometimes above error is there and then stops working. Aferwords no request can reach to server.

    Method from retrofit interface

    @GET("/v1/app_endpoint/{keyword}/")
    Observable<Model> details(@Path("keyword") String keyword);
    

    Below few helper methods just for check configuration if anything required.

    public static Retrofit retrofit() {
        return provideRetrofit(provideGson(), provideOkHttpClient());
    }
    
    public static Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
        gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
        gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }
    
            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        });
        gsonBuilder.registerTypeAdapterFactory(AutoValueGsonTypeAdapterFactory.create());
        return gsonBuilder.create();
    }
    
    public static OkHttpClient provideOkHttpClient() {
        return new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(600, TimeUnit.SECONDS)
                .readTimeout(1, TimeUnit.MINUTES)
                .retryOnConnectionFailure(true)
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request newRequest = chain.request().newBuilder()
                                .addHeader("Content-Type", "application/json")
                                .addHeader("User-Agent", "Android-App")
                                .build();
                        return chain.proceed(newRequest);
                    }
                })
                .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                .build();
    }
    
    public static Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .baseUrl(BuildConfig.API_URL)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
                .build();
    }
    

    Dependencies

    // Networking
    compile 'com.squareup.okhttp3:okhttp:3.4.2'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    
    • Mark
      Mark over 7 years
      Did you ever get a resolution for this issue? I'm seeing similar random error using multiple asynchronous http requests using okhttp 3.5.0 / RxJava 2 / Jackson.