0

A few users are experiencing constant app crashes since they updated to Android 12. Issue doesn't happen on any of my or my friends devices (also Android 12) so I can't figure out how to fix it. I don't pass a null value here so I'm not sure what is causing the crash. AccessToken is never null or if it would ever be null, value would be "Bearer null". I tried adding null checks, extra logs to get more info, I'm really out of ideas. Does anyone know how I can identify what's causing the problem or if there are any issues in the code below ?

stack trace from firebase

Fatal Exception: java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter value
       at okhttp3.Request$Builder.addHeader(:7)
       at uk.co.evezy.driver.network.interceptors.RequestInterceptor.intercept(RequestInterceptor.kt:33)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at uk.co.evezy.driver.network.interceptors.NetworkConnectionInterceptor.intercept(NetworkConnectionInterceptor.kt:31)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at uk.co.evezy.driver.network.interceptors.UserAgentInterceptor.intercept(UserAgentInterceptor.kt:47)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
       at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
       at java.lang.Thread.run(Thread.java:920)

Interceptor I'm using

class RequestInterceptor @Inject constructor(private val userDataManager: UserDataManager, private val refreshTokenService: RefreshTokenService) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {

        var accessToken = ""

        if (userDataManager.getUserAccessData() != null) {
            accessToken = "Bearer ${userDataManager.getAuthToken()}"

            if (userDataManager.isAuthTokenExpired()) {
                accessToken = ""
                runBlocking {
                    accessToken = "Bearer ${refreshTokenService.getNewTokenUsingRefreshToken()}"
                }
            }
        }

        val original = chain.request()
        val builder = original.newBuilder()
            .method(original.method, original.body)
            .addHeader("Authorization", accessToken)
        val newRequest = builder.build()

        return chain.proceed(newRequest)
    }
}

The other 2 interceptors just in case

class UserAgentInterceptor @Inject constructor() : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
            val original = chain.request()

            Timber.d("UserAgentInterceptor: ${chain.request()}")

            val newUserAgent = String.format(
                Locale...,
                "%s %s(%s) (Android %s;  Model: %s;  Brand: %s;  Device: %s; %s)",
                "appName",
                BuildConfig.VERSION_NAME,
                BuildConfig.VERSION_CODE,
                Build.VERSION.RELEASE,
                Build.MODEL,
                Build.BRAND,
                Build.DEVICE,
                Locale.getDefault().language
            )

            val builder = original.newBuilder()
                .header("User-Agent", newUserAgent)
                .method(original.method, original.body)
            val newRequest = builder.build()

            return chain.proceed(newRequest)
    }
}
class NetworkConnectionInterceptor @Inject constructor(private val application: Application) :
    Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {

            Timber.d("NetworkConnectionInterceptor: ${chain.request()}")

            val request = chain.request()
            val response = chain.proceed(request)

            if (!isInternetAvailable()) {
                throw NoInternetException("No active internet connection")
            }

            return response
    }
    (...)
    }

Craxx
  • 23
  • 1
  • 6
  • That seems like an android VM bug, it doesn't look like it should be able to happen. If it's specifically this location, you can probably add additional checks for null, and log when it happens. Make the var nullable, and protect the addHeader call. – Yuri Schimke Dec 03 '21 at 08:27

0 Answers0