首页 > 解决方案 > 如何区分在没有互联网连接的情况下引发的异常与没有可用服务器/或错误 url 的情况?

问题描述

我有这个when(kotlin)/switch case(java)java.net为我的请求提供了例外。问题是它会抛出UnknownHostException两种情况:

  1. 当我没有联系时。

  2. 当我插入一个损坏的 url 时(这相当于服务器完全不可用)。

如果它们抛出相同的异常,我如何区分这两种情况?我应该在每次请求之前检查用户的连接吗?

何时/尝试捕获

            is SocketTimeoutException -> {
                 //Server takes too long to respond
            }
            is UnknownHostException -> {
                 //No connection and broken url / no server at all
            }
            is HttpException -> {
                 //server error response
            }
            else -> {
                 //Any other case
            }

标签: javaandroidkotlin

解决方案


您需要在 OkHttpClient 中创建一个像拦截器一样的异常:
在 OkHttpClient 中:.addInterceptor(ConnectivityInterceptor(context))


class ConnectivityInterceptor(private val mContext: Context) : Interceptor {
    @Throws(IOException::class)
    override fun intercept(chain: Chain): Response {
        if (!NetworkUtil.isOnline(mContext)) {
            throw NoInternet()
        }
        val builder = chain.request().newBuilder()
        return chain.proceed(builder.build())
    }

}


class NoInternet : IOException() {

    override val message: String?
        get() {
            return "No connectivity exception"
        }

}

class NetworkUtil {
    companion object {
        fun isOnline(context: Context): Boolean {
            var result = false
            val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val networkCapabilities = connectivityManager.activeNetwork ?: return false
                val actNw =
                    connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
                result = when {
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            } else {
                connectivityManager.run {
                    connectivityManager.activeNetworkInfo?.run {
                        result = when (type) {
                            ConnectivityManager.TYPE_WIFI -> true
                            ConnectivityManager.TYPE_MOBILE -> true
                            ConnectivityManager.TYPE_ETHERNET -> true
                            else -> false
                        }
                    }
                }
            }
            return result
        }
    }
}

你在什么时候使用

       is NoInternet -> {
}

推荐阅读