okhttp - 拦截器 - 阻止非致命异常记录到 Crashlytics

2022-09-04 04:42:41

我在Android应用程序中使用Retrofit,这反过来又意味着我使用OkHttp。我刚刚去了Alpha,在我的崩溃分析中看到一些非致命的异常被记录下来。所有这些都源于我的okhttp拦截器,然后记录的异常似乎都是在网络不稳定或连接断开等情况下有效的事情。

我怎样才能使这些异常不会注销到崩溃状态,从而使我对应用程序中发生的异常的视图变得混乱?


一些例外情况示例:

> Non-fatal Exception: javax.net.ssl.SSLHandshakeException
Connection closed by peer
okhttp3.internal.connection.RealConnection.connectTls (RealConnection.java:281)
okhttp3.internal.connection.RealConnection.establishProtocol (RealConnection.java:251)
okhttp3.internal.connection.RealConnection.connect (RealConnection.java:151)
okhttp3.internal.connection.StreamAllocation.findConnection (StreamAllocation.java:192)
okhttp3.internal.connection.StreamAllocation.findHealthyConnection (StreamAllocation.java:121)
okhttp3.internal.connection.StreamAllocation.newStream (StreamAllocation.java:100)
okhttp3.internal.connection.ConnectInterceptor.intercept (ConnectInterceptor.java:42)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
okhttp3.internal.cache.CacheInterceptor.intercept (CacheInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
okhttp3.internal.http.BridgeInterceptor.intercept (BridgeInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (RetryAndFollowUpInterceptor.java:120)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
MY_INTERCEPTOR.intercept (AuthenticationInterceptor.java:30)

> Non-fatal Exception: javax.net.ssl.SSLException
Read error: ssl=0xdee45cc0: I/O error during system call, Software caused connection abort
okio.Okio$2.read (Okio.java:139)
okio.AsyncTimeout$2.read (AsyncTimeout.java:237)
okio.RealBufferedSource.indexOf (RealBufferedSource.java:345)
okio.RealBufferedSource.readUtf8LineStrict (RealBufferedSource.java:217)
okio.RealBufferedSource.readUtf8LineStrict (RealBufferedSource.java:211)
okhttp3.internal.http1.Http1Codec.readResponseHeaders (Http1Codec.java:189)
okhttp3.internal.http.CallServerInterceptor.intercept (CallServerInterceptor.java:75)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.connection.ConnectInterceptor.intercept (ConnectInterceptor.java:45)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
okhttp3.internal.cache.CacheInterceptor.intercept (CacheInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
okhttp3.internal.http.BridgeInterceptor.intercept (BridgeInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (RetryAndFollowUpInterceptor.java:120)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
MY_INTERCEPTOR.intercept (AuthenticationInterceptor.java:30)

这是我的拦截器代码:

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    Response response = chain.proceed(request);

    if( response.code() == HTTP_AUTHENTICATION_ERROR_CODE ){
        Intent intent = new Intent(ACTION_LOGOUT_ACTION);
        mContext.sendBroadcast(intent);
    }
    return response;
}

我知道我可以从“继续”调用中捕获任何IOException,但这不会搞砸OkHttp对网络错误等的正确处理吗?


答案 1

当您在代码中显式调用 Crashlytics.logException(Exception) 时,将记录非致命异常

请阅读以下信息:

Crashlytics对于Android,您可以在应用程序的捕获块中记录捕获的异常!要使用此功能,只需向 catch 块添加一个调用:Crashlytics.logException(Exception)

try {
  myMethodThatThrows();
} catch (Exception e) {
  Crashlytics.logException(e);
  // handle your exception here! 
}

所有记录的异常都将在 Crashlytics 仪表板中显示为“非致命”问题。您的问题摘要将包含您用于从崩溃中获取的所有状态信息,以及按 Android 版本和硬件设备细分的问题。


答案 2

当您使用
Crashlytics.logException()时,Crashlytics仅存储非致命异常,请参阅下面的代码以获取拦截器,它正在引发IOException,但异常在仪表板上的非致命异常部分不可见,而我们不会记录它。

@Override 
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();

long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
    request.url(), chain.connection(), request.headers()));

Response response = chain.proceed(request);

long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
    response.request().url(), (t2 - t1) / 1e6d, response.headers()));

return response;
} 

所以如果你想在非致命异常下记录异常,只需使用Crashlytics.logException();

和 Crashlytics 仅存储给定应用会话中最近的 8 个异常。如果您的应用在一个会话中引发超过 8 个异常,则较旧的异常将丢失。


推荐