简体   繁体   English

Kotlin 异常没有被捕获?

[英]Kotlin Exception not caught?

I'm wondering why with the following code the exception doesn't get caught:我想知道为什么使用以下代码不会捕获异常:

private inline fun <reified T : Any> parseResponse(
        httpConnection: HttpURLConnection,
        noinline callback: ResponseBlock<T>?
    ) {
        with(httpConnection) {
            var error: Throwable? = null
            val model = try {
                if (this.responseCode in 200..299) {
                    jacksonObjectMapper().readValue(
                        this.inputStream.bufferedReader().readText(),
                        T::class.java
                    )
                } else {
                    null
                }
            } catch (e: Exception) {
                error = e
                null
            }

            if (model == null && error == null) {
                error = try {
                    if (this.responseCode !in 200..299) {
                        val errorResponse = this.errorStream.bufferedReader().readText()
                        Throwable(errorResponse)
                    } else {
                        null
                    }
                } catch (e: Exception) {
                    e
                }
            }
            error?.let {
                Log.e(this::class.simpleName, it.message, it)
            }
            callback?.invoke(this.responseCode, model, error)
            this.disconnect()
        }
    }

The function gets called like this: function 被这样调用:

private inline fun <reified T : Any> get(
        pathComponents: Array<String>,
        noinline callback: ResponseBlock<T>?,
        queryParameters: Map<String, Any>? = null
    ) {
        thread(start = true) {
            val urlRequest = createUrlRequest(HttpMethod.GET, pathComponents, queryParameters)
            parseResponse(urlRequest, callback)
        }
    }

And still I get this exception which causes the app to crash:我仍然得到这个导致应用程序崩溃的异常:

E/HttpURLConnectionImpl: Failed to connect to /10.0.2.2:8080
    java.net.ConnectException: Failed to connect to /10.0.2.2:8080
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:147)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at io.openremote.app.network.ApiManager$getAppConfig$$inlined$get$1.invoke(ApiManager.kt:148)
        at io.openremote.app.network.ApiManager$getAppConfig$$inlined$get$1.invoke(ApiManager.kt:14)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
    Process: io.openremote.app, PID: 3901
    java.net.ConnectException: Failed to connect to /10.0.2.2:8080
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:147)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at io.openremote.app.network.ApiManager$getAppConfig$$inlined$get$1.invoke(ApiManager.kt:148)
        at io.openremote.app.network.ApiManager$getAppConfig$$inlined$get$1.invoke(ApiManager.kt:14)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)

I would say the try/catch blocks would catch the exception, but alas...我会说 try/catch 块会捕获异常,但是唉...

What causes the exception not being caught?是什么导致异常没有被捕获? I would say threading doesn't matter because I use try/catch blocks to handle exceptions in the thread.我会说线程无关紧要,因为我使用 try/catch 块来处理线程中的异常。

Update更新

After Laalto's answer, I've updated the code to look like this (for those who are interested):在 Laalto 的回答之后,我将代码更新为如下所示(对于那些感兴趣的人):

private inline fun <reified T : Any> parseResponse(
        httpConnection: HttpURLConnection,
        noinline callback: ResponseBlock<T>?
    ) {
        with(httpConnection) {
            val parsedResult = try {
                if (this.responseCode in 200..299) {
                    Triple(
                        this.responseCode, jacksonObjectMapper().readValue(
                            this.inputStream.bufferedReader().readText(),
                            T::class.java
                        ), null
                    )
                } else {
                    val errorResponse = this.errorStream.bufferedReader().readText()
                    Triple(this.responseCode, null, Throwable(errorResponse))
                }
            } catch (e: Exception) {
                Triple(0, null, e)
            }

            parsedResult.third?.let {
                Log.e(this::class.simpleName, it.message, it)
            }
            callback?.invoke(parsedResult.first, parsedResult.second, parsedResult.third)
            this.disconnect()
        }
    }

The stacktrace shows an exception trying to call getResponseCode() .堆栈跟踪显示尝试调用getResponseCode()的异常。 There's one access to responseCode without a try - catch block at the end:在没有try - catch块的情况下可以访问responseCode

callback?.invoke(this.responseCode, model, error)

Earlier catch blocks work just fine but the code goes on to execute this part that then throws an exception.早期的 catch 块工作得很好,但代码继续执行这部分,然后引发异常。

As in your updated question, you have already restructured the code around this issue.与您更新的问题一样,您已经围绕此问题重组了代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM