android - 如何在 Android 的 OkHttp 拦截器中处理 IOExceptions?
问题描述
我有一个自定义拦截器将 API 密钥附加到 API 请求。这是代码:
public class HeaderInterceptor implements Interceptor {
private final ProfileDbDataSource profileDbRepository;
@Inject public HeaderInterceptor(ProfileDbDataSource profileDbRepository) {
this.profileDbRepository = profileDbRepository;
}
@NonNull @Override public Response intercept(@NonNull Chain chain) throws IOException {
if (!chain.request().url().toString().contains(Constants.GET_API_KEY)) {
Request.Builder requestBuilder = attachApiKeyAsQueryParam(chain);
return chain.proceed(requestBuilder.build());
}
return chain.proceed(chain.request());
}
private Request.Builder attachApiKeyAsQueryParam(Chain chain) {
String apiKey = profileDbRepository.getLoggedInProfile().blockingGet().getApiKey();
Request original = chain.request();
HttpUrl originalHttpUrl = original.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter(Constants.USER_API_KEY, apiKey)
.build();
return original.newBuilder().url(url);
}
}
我看到在线上发生了一些崩溃return chain.proceed(requestBuilder.build());
,所有这些异常都是IOException
.
我见过SocketTimeoutException
,UnknownHostException
和ConnectException
。
这是一个堆栈跟踪:
io.reactivex.exceptions.UndeliverableException:
at io.reactivex.plugins.RxJavaPlugins.onError (RxJavaPlugins.java:367)
at io.reactivex.internal.operators.observable.ObservableFlatMapSingle$FlatMapSingleObserver.innerError (ObservableFlatMapSingle.java:204)
at io.reactivex.internal.operators.observable.ObservableFlatMapSingle$FlatMapSingleObserver$InnerObserver.onError (ObservableFlatMapSingle.java:289)
at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError (SingleFlatMap.java:90)
at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.onError (SingleSubscribeOn.java:73)
at io.reactivex.internal.operators.observable.ObservableSingleSingle$SingleElementObserver.onError (ObservableSingleSingle.java:93)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onError (BodyObservable.java:72)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual (CallExecuteObservable.java:59)
at io.reactivex.Observable.subscribe (Observable.java:12284)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual (BodyObservable.java:34)
at io.reactivex.Observable.subscribe (Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual (ObservableSingleSingle.java:35)
at io.reactivex.Single.subscribe (Single.java:3666)
at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run (SingleSubscribeOn.java:89)
at io.reactivex.Scheduler$DisposeTask.run (Scheduler.java:608)
at io.reactivex.internal.schedulers.ScheduledRunnable.run (ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call (ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run (FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run (ScheduledThreadPoolExecutor.java:301)
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:923)
Caused by: java.net.SocketTimeoutException:
at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException (Http2Stream.kt:677)
at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut (Http2Stream.kt:686)
at okhttp3.internal.http2.Http2Stream.takeHeaders (Http2Stream.kt:143)
at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders (Http2ExchangeCodec.kt:96)
at okhttp3.internal.connection.Exchange.readResponseHeaders (Exchange.kt:106)
at okhttp3.internal.http.CallServerInterceptor.intercept (CallServerInterceptor.kt:79)
at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.kt:109)
at okhttp3.logging.HttpLoggingInterceptor.intercept (HttpLoggingInterceptor.kt:221)
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 com.anstar.data.core.HeaderInterceptor.intercept (HeaderInterceptor.java:24)
at okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp (RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute (RealCall.kt:154)
at retrofit2.OkHttpCall.execute (OkHttpCall.java:204)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual (CallExecuteObservable.java:45)
解决方案
这不是您的拦截器的问题,而是您如何使用网络请求的 Rx 流的问题。IOExceptions 通常是预期的错误,您应该准备好在执行 I/O 时捕获和处理它们。onError
要使用 Rx Observable 执行此操作,请在调用时为参数传递错误处理程序subscribe
:
apiClient.request()
.subscribe(
/* onNext */ (response) -> /* handle response */,
/* onError */ (error) -> /* handle error */
)
推荐阅读
- javascript - HTML5 websocket 客户端未检测到意外的服务器断开连接
- python - 我在 text_classification_rnn 的 Google tensorflow2.0 教程中遇到了一个令人惊讶的错误
- c# - 运算符逻辑与与内联如果其他不兼容
- rpm - RPM 规范在帖子中使用前缀
- junit - 使用 MiniSolrCloudCluster 创建集群时出错
- android - 不自动显示软键盘
- python - Django 1.11 - 将时区为 2018-01-01T00:00:00+03:00 的日期时间字符串转换为用于查询集的日期时间对象
- android - 如何从 Flutter 中的 mapbox 获取当前位置
- pascal - 将具有整数值和字符索引的数组传递给 Pascal 中的函数
- python - 在布尔字段上查询 JSON 列