Android库在try块中抛出异常,捕获所有Throwable

时间:2018-04-23 15:24:30

标签: java android kotlin

我们已经编写了一个Kotlin库来处理一些网络逻辑。该库本身包含使用AsyncTask中的HttpURLConnection工具的java.net.*

private inner class ClickstreamTask(
                                    headers: HashMap<String, String>,
                                    params: Request,
                                    success: (() -> Unit)? = null,
                                    failure: ((statusCode: Int?, json: 
HashMap<String, String>?) -> Unit)? = null) : AsyncTask<Void, Unit, Unit>() {

    private var headers: HashMap<String, String> = headers
    private var paramaters: Request = params
    private var success: (() -> Unit)? = success
    private var failure: ((statusCode: Int?, json: HashMap<String, String>?) -> Unit)? = failure

    override fun doInBackground(vararg params: Void){

        val url = try {
            URL(getURLString() + path)
        } catch (e: Exception) {
            failure?.invoke(null, hashMapOf("error" to "Invalid URL."))
            return Unit
        }

        var request = try{
            url.openConnection() as HttpURLConnection
        } catch (e: Exception){
            failure?.invoke(null, hashMapOf("error" to "Unable to establish connection"))
            return Unit
        }

        request.doInput = false
        request.doOutput = true
        val mapper = jacksonObjectMapper()

        request.requestMethod = "POST"
        val httpBody = try {
            mapper.writeValueAsBytes(paramaters)
        } catch (e: Exception) {
            failure?.invoke(null, hashMapOf("error" to "Invalid params."))
            return Unit
        }

        for ((key, value) in headers) {
            request.setRequestProperty(key, value)
        }

        try{
            request.outputStream.write(httpBody)
        }catch (e: Throwable){
            request.outputStream.close()
            failure?.invoke(null, hashMapOf("error" to "Issue writing to URL"))
            return Unit
        }
        request.outputStream.close()


        if (request.responseCode != 200){
            failure?.invoke(request.responseCode, hashMapOf("Failed request" to request.responseMessage))
            return Unit
        }

        success?.invoke()
        return Unit
    }
}

当我们使用在飞行模式下运行库的Android应用程序时,应用程序因未捕获的异常而崩溃&#34; UnknownHostException&#34;:

  

引起:java.net.UnknownHostException:无法解析主机   &#34; ste03lbclkapp00.iteclientsys.local&#34;:没有与之关联的地址   主机名在   java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:141)     在   java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)     在java.net.InetAddress.getAllByName(InetAddress.java:787)at   com.android.okhttp.Dns $ 1.lookup(Dns.java:39)at   com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)     在   com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)     在   com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)     在   com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)     在   com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)     在   com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)     在   com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)     在   com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)     在   com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)     在   com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)     在   com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)     在   com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)     在   com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(未知   资料来源:0)at   com.tdameritrade.amerivest.clickstreamshared.Network.NetworkManager $ ClickstreamTask.doInBackground(NetworkManager.kt:87)     在   com.tdameritrade.amerivest.clickstreamshared.Network.NetworkManager $ ClickstreamTask.doInBackground(NetworkManager.kt:43)     在android.os.AsyncTask $ 2.call(AsyncTask.java:333)at   java.util.concurrent.FutureTask.run(FutureTask.java:266)... 4更多   引起:android.system.GaiException:android_getaddrinfo失败:   EAI_NODATA(与主机名无关的地址)at   libcore.io.Linux.android_getaddrinfo(Native Method)at   libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:59)at at   java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:122)     ......还有24个

抛出异常的行是request.outputStream.write(httpBody)。但是,我们将该行包装在处理try / catch的{​​{1}}中。

如果Throwable第87行将其包裹在捕获中时如何抛出异常?

1 个答案:

答案 0 :(得分:1)

此代码:

    try{
        request.outputStream.write(httpBody)
    }catch (e: Throwable){
        request.outputStream.close()
        failure?.invoke(null, hashMapOf("error" to "Issue writing to URL"))
        return Unit
    }

将尝试在catch块中执行操作,该操作也会生成异常:

        request.outputStream.close()

这是未被捕获的 - 但如果您在访问输出流时处理某些错误,这似乎也是不明智的。

异常跟踪表示更多的原因造成的,并且我猜你还要进一步挖掘这个。