由于服务器和客户端网络连接,我正在尝试处理异常。 我制作了一个Interceptor类,用于以正方形文档的形式全局处理这些错误。 每次我尝试在没有网络连接的情况下执行网络呼叫时,都会出现此错误并导致我的应用崩溃。
已编辑:如果连接速度太慢而无法触发SocketTimeOutExeception,则也会导致应用程序崩溃。我试图用一种仅在存在活动网络连接时才执行网络调用的方式来覆盖它。但是就像我之前说的那样,连接速度太慢,错误与SocketTimeOutExeception完全相同。该应用程序可以通过良好的活动网络连接正常运行
W/System.err: java.net.UnknownHostException: Unable to resolve host "0725394a.ngrok.io": No address associated with hostname
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:157)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
W/System.err: at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:49)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:164)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:129)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:197)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:107)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:75)
at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:245)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:74)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at com.network.di.AuthenticationInterceptor.intercept(AuthenticationInterceptor.kt:63)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at com.network.exception.NetworkExceptionInterceptor.intercept(NetworkExceptionInterceptor.kt:11)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at com.readystatesoftware.chuck.ChuckInterceptor.intercept(ChuckInterceptor.java:172)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute(DefaultCallAdapterFactory.java:97)
W/System.err: at com.network.datasource.CourseDetailsDataSourcecImpl.getChaptersByPagination(CourseDetailsDataSourcecImpl.kt:39)
at com.data.repository.CourseDetailsRepositoryImpl.getChapterList(CourseDetailsRepositoryImpl.kt:19)
at com.domain.interactors.coursedetails.GetCourseChaptersByPagination$provideObservable$1.call(GetCourseChaptersByPagination.kt:26)
at com.domain.interactors.coursedetails.GetCourseChaptersByPagination$provideObservable$1.call(GetCourseChaptersByPagination.kt:11)
at io.reactivex.internal.operators.observable.ObservableFromCallable.subscribeActual(ObservableFromCallable.java:43)
at io.reactivex.Observable.subscribe(Observable.java:12246)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
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:764)
这是我一直遇到的错误。
这是我的拦截器类
class AuthenticationInterceptor() : Interceptor {
private var bearerToken : String? = ""
private var token : String? = ""
private var customToken : String? = null
private var customTag : String? = null
private var onlyUseCustomHeader : Boolean = false
private var customName : String? = null
fun setCustom(customName : String? , customTag : String? , customToken : String?) {
this.customToken = customToken
this.customTag = customTag
this.customName = customName
}
fun setOnlyUseCustomHeader(onlyUseCustomHeader : Boolean) {
this.onlyUseCustomHeader = onlyUseCustomHeader
}
constructor(
bearerToken : String?,
token : String?
) : this() {
this.bearerToken = bearerToken
this.token = token
}
@Throws(IOException::class)
override fun intercept(chain : Interceptor.Chain) : Response {
val builder = chain.request().newBuilder()
if (!onlyUseCustomHeader) {
if (customName != null && customToken != null) {
if (customTag == null)
builder.addHeader("$customName" , "$customToken")
else
builder.addHeader("$customName" , "$customTag $customToken")
}
if (bearerToken != null && bearerToken != "")
builder.addHeader("Authorization" , "Bearer $bearerToken")
if (token != null && token != "")
builder.addHeader("token" , "$token")
} else {
if (customName != null && customToken != null) {
if (customTag == null)
builder.addHeader("$customName" , "$customToken")
else
builder.addHeader("$customName" , "$customTag $customToken")
}
}
builder.addHeader("Accept" , "application/json")
val request = builder.build()
return chain.proceed(request)
}
}
class NetworkExceptionInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request())
when (response.isSuccessful) {
true -> return response
false -> {
throw NetworkException(response.body , response.code)
}
}
}
}
这是我的自定义错误类。
data class NetworkException constructor(
var errorBody: ResponseBody? = null,
var errorCode: Int
) : IOException()
这些是提供OkhttpClient和Retrofit.Builder()的方法,我在其中添加了网络拦截器和身份验证拦截器。
@Provides
fun providesOkHttpClientBuilder(context : Context) : OkHttpClient.Builder {
return OkHttpClient.Builder().apply {
val loggerInterceptor = HttpLoggingInterceptor().apply {
level = when (BuildConfig.DEBUG) {
true -> HttpLoggingInterceptor.Level.HEADERS
false -> HttpLoggingInterceptor.Level.NONE
}
}
addInterceptor(loggerInterceptor)
.addInterceptor(ChuckInterceptor(context))
.addInterceptor(NetworkExceptionInterceptor())
.readTimeout(8 , TimeUnit.SECONDS)
.writeTimeout(8 , TimeUnit.SECONDS)
.connectTimeout(8 , TimeUnit.SECONDS)
.cache(null)
}
}
@JvmStatic
@NonNull
@Named("authenticatedBuilder")
@Provides
fun getAuthenticatedBuilder(@Named("bearer_token") bearerToken : String? , @Named("token") token : String? , httpClientBuilder : OkHttpClient.Builder ,@Named("primary") retrofitBuilder : Retrofit.Builder) : Retrofit.Builder {
showLogD("NETWORK_MODULE" , "BearerToken before interception : $bearerToken")
showLogD("NETWORK_MODULE" , "TOKEN before interception : $token")
val interceptor : Interceptor =
AuthenticationInterceptor(bearerToken , token)
if (!httpClientBuilder.interceptors().contains(interceptor)) {
httpClientBuilder.addInterceptor(interceptor)
}
return retrofitBuilder.client(httpClientBuilder.build())
}
编辑2:这是CourseDetailsDataSourceImpl.kt
class CourseDetailsDataSourcecImpl @Inject constructor(
private val courseDetailsService : CourseDetailsService ,
private val courseDetailsMapper : CourseDetailsMapper ,
private val chapterListMapper : CourseChapterListMapper ,
private val lessonSnapShotMapper : LessonSnapShotMapper ,
private val vdoPlayerOTPMapper : VdoPlayerOTPMapper
) : CourseDetailsDataSource {
@Inject
lateinit var vdoPlayerService : VdoPlayerService
override fun getCourseDetails(courseID : String) : CourseDetailsVO {
return courseDetailsMapper.map(courseDetailsService.getCourseDetails(courseID).execute().body()!!)
}
override fun getCourseVideoDetails(lessonID : String) : LessonSnapShotVO {
return lessonSnapShotMapper.map(courseDetailsService.getLessonDetails(lessonID).execute().body()!!)
}
override fun getChaptersByPagination(courseID : String , pageNumber : Int) : CourseChapterListVO{
//todo implement this with pagination
return chapterListMapper.map(courseDetailsService.getCourseChapters(courseID).execute().body()!!)
}
override fun getVdoPlayerOtp(videoID : String) : VdoPlayerOTPResponseVO {
return vdoPlayerOTPMapper.map(vdoPlayerService.getOtp( videoID , VDOOTPRequestBody()).execute().body()!!)
}
}
任何想法如何解决这个问题?
答案 0 :(得分:1)
我正在使用onErrorReturn方法,就像我在使用Flatmap链式调用多个网络调用一样。这样做的副作用是onErrorReturn不会消耗由于某种故障而由网络调用引发的异常,因此它会引发异常,因此应用程序不可避免地崩溃了。这就是为什么我改用onErrorResumeNext的原因。然后崩溃消失了,因为它吞下了异常,并且抛出的异常可以由我们自己处理。