首页 > 解决方案 > OkHttp 拦截器不断返回 null 并使应用程序崩溃

问题描述

我有一个 OkHttp 客户端,它使用我的自定义网络拦截器将令牌插入到请求标头中。

我不断收到异常

E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher 
   Process: com.edstart.tazuzu, PID: 32093
   java.lang.NullPointerException: interceptor com.edstart.tazuzu.RestAPI.RequestsErrorInterceptor@2bde70f returned null
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:157)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at com.edstart.tazuzu.RestAPI.TazuzuRequestsInterceptor.intercept(TazuzuRequestsInterceptor.kt:30)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

我试过用 try/catch 包围拦截器。并且还抛出错误以避免应用程序崩溃但没有好的结果。

拦截器代码:

package com.edstart.tazuzu.RestAPI

import android.util.Log
import com.edstart.tazuzu.Managers.ServerManager
import okhttp3.Interceptor
import okhttp3.Response
import java.net.InetAddress
import kotlin.Exception

/**
 * interceptor for the tazuzu api requests to insert the token before the request
 * send to the server (for authentication)
 */
class TazuzuRequestsInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain?): Response? {
        try {

            if (!isInternetAvailable()) {
                throw Exception()
            } else {
                var request = chain?.request()

                if (request != null) {
                    val builder = request.newBuilder()
                    if (builder != null) {
                        builder.addHeader("x-access-token", ServerManager.token)

                        request = builder.build()
                        if (request != null && chain != null) {
                            return chain.proceed(request)
                        }
                    }
                }
            }
        } catch (e: java.lang.Exception) {
            Log.e("###", e.toString())
            throw e
        }
        return null
    }

    private fun isInternetAvailable(): Boolean {
        return try {
            val ipAddr = InetAddress.getByName("google.com")
            //You can replace it with your name
            !ipAddr.equals("")

        } catch (e: Exception) {
            false
        }

    }

请帮助,寻找以不会使应用程序崩溃的方式控制异常的方法。

标签: androidkotlinretrofitokhttp

解决方案


几条笔记

你不应该传入null拦截器

什么地方出了错

Null 传递给下游链

你可以做什么

class ErrorHandlingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)

        if (!isInternetAvailable()) {
            // Do your thing
            // 1. Either throw a generic exception
            // 2. Throw an exception with your own custom status code that can be checked on the callbacks
            // 3. Create an interface callback

            // example throw invocation
            throw Exception()
        } else {
            val builder = request.newBuilder()
            builder?.let { builder ->
                builder.addHeader("x-access-token", ServerManager.token)
            }
            request = builder.build()

            // No need for this additional checks
            // if (request != null && chain != null) { ... }

            return chain.proceed(request)
        }
    }
}


private fun isInternetAvailable(): Boolean {
    return try {
        val ipAddr = InetAddress.getByName("google.com")
        //You can replace it with your name
        !ipAddr.equals("")

    } catch (e: Exception) {
        false
    }

}

例如,如果您选择在没有互联网连接时抛出异常,您可以只处理onFailure()调用回调中的所有内容retrofit

或者,如果您正在使用rxjava,您可以在错误回调处理程序上订阅错误。

阅读更多


推荐阅读