Firebase Crashlytics用Retrofit和coroutines报告安卓项目的假崩溃。

问题描述 投票:0回答:1

Crashlytics在我的项目中报告了当某个网络请求返回400时的崩溃。我已经能够复制这个问题,应用程序正在按照预期显示错误弹出,但它没有崩溃。我很有信心,应用程序没有以Crashlytics中的指示速度崩溃,然而,我很担心这些数字,我希望它们是准确的。

最重要的是,Crashlytics显示,这种崩溃发生在非常老的版本的应用程序中,而它并没有发生(在kotlin或coroutines被添加到项目中之前)。

这里是堆栈跟踪。

Fatal Exception: retrofit2.HttpException: HTTP 400 Bad Request
   at retrofit2.KotlinExtensions$await$2$2.onResponse + 49(KotlinExtensions.java:49)
   at retrofit2.OkHttpCall$1.onResponse + 129(OkHttpCall.java:129)
   at okhttp3.RealCall$AsyncCall.execute + 174(RealCall.java:174)
   at okhttp3.internal.NamedRunnable.run + 32(NamedRunnable.java:32)
   at java.util.concurrent.ThreadPoolExecutor.runWorker + 1113(ThreadPoolExecutor.java:1113)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run + 588(ThreadPoolExecutor.java:588)
   at java.lang.Thread.run + 818(Thread.java:818)

有谁经历过这样的问题,或者可能知道这里发生了什么?

android kotlin okhttp crashlytics coroutine
1个回答
1
投票

更新

我已经找到了问题所在。我有一个这样的请求。

viewModelScope.launch {
    try {
        val response1 = api.request1()
        launch {
            val response2 = api.request2()
            ...
        }
    } catch (e: Exception) {
        Log.e("TAG", "Error", e)
    }
}

我没有一个 try catch 块内的第二个coroutine。因为是不同的coroutine,异常不会被父程序捕获,所以你需要在那里也捕获异常。

老答案。

我也有同样的问题 从Rx到Coroutine的所有请求重写后开始的。报告在Play Console和Crashlytics中都显示了不同的异常。

以下是我的代码示例。

@Singleton
@Provides
fun providesApi(client: OkHttpClient, gsonConverterFactory: GsonConverterFactory): Api {
    return Retrofit.Builder()
            .baseUrl("https://url")
            .client(client.newBuilder().addInterceptor { chain ->
                val request = chain.request().newBuilder()
                        .addHeader("Header1", ...)
                        .addHeader("Header2", ...)
                        .build()
                chain.proceed(request)   
            }.build())
            .addConverterFactory(gsonConverterFactory)
            .build()
            .create(Api::class.java)
}

viewModelScope.launch {
    try {
        val response = api.request()
    } catch (e: Exception) {
        Log.e("TAG", "Error", e)
    }
}

报告显示它在以下情况下崩溃 chain.proceed(request). 但是当我试图通过设置1秒的超时或者甚至在拦截器中手动抛出一个异常来重现它时,所有的异常都在try块中被捕获,而且根本没有崩溃。例子异常。

java.net.SocketTimeoutException: 
  at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException (Http2Stream.java:4)
  at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut (Http2Stream.java:8)
  at okhttp3.internal.http2.Http2Stream.takeHeaders (Http2Stream.java:24)
  at okhttp3.internal.http2.Http2Codec.openResponseBody (Http2Codec.java:2)
  at okhttp3.internal.http.CallServerInterceptor.intercept (CallServerInterceptor.java:27)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.connection.ConnectInterceptor.intercept (ConnectInterceptor.java:4)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:69)
  at okhttp3.internal.cache.CacheInterceptor.intercept (CacheInterceptor.java:69)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:27)
  at okhttp3.internal.http.BridgeInterceptor.intercept (BridgeInterceptor.java:27)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (RetryAndFollowUpInterceptor.java:70)
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.http.RealInterceptorChain.a (RealInterceptorChain.java:6)
  at myproject.dagger.Module$providesApi$1.intercept (Module.java:4) <------------------ HERE
  at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:2)
  at okhttp3.internal.http.RealInterceptorChain.a (RealInterceptorChain.java:6)
  at okhttp3.RealCall.getResponseWithInterceptorChain (RealCall.java:12)
  at okhttp3.RealCall$AsyncCall.execute (RealCall.java:9)
  at okhttp3.internal.NamedRunnable.run (NamedRunnable.java:17)
  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)

异常的例子:

retrofit2.HttpException: 
  at retrofit2.KotlinExtensions$await$2$2.onResponse (KotlinExtensions.java:2)
  at retrofit2.OkHttpCall$1.onResponse (OkHttpCall.java)
  at okhttp3.RealCall$AsyncCall.a (RealCall.java)
  at okhttp3.internal.NamedRunnable.run (NamedRunnable.java)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1112)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:587)
  at java.lang.Thread.run (Thread.java:841)

真的很沮丧,因为我每天都会收到成千上万的报告。


-1
投票

那么Firebase不会报告一个 Crash 除非在终端用户的设备上运行的应用程序导致了 ANR(Application Not Responding) 错误。

我建议如果可能的话,在其他物理设备上测试应用程序,或者在多个不同的android模拟器上使用firebase报告的版本代码来测试失败。

© www.soinside.com 2019 - 2024. All rights reserved.