【发布时间】:2020-08-27 17:49:47
【问题描述】:
我将 Ktor 与 kotlin 多平台一起使用,我试图弄清楚为什么我没有收到任何抛出的异常。在我的客户端配置中,我使用HttpResonseValidator 检查返回的状态代码
private val client = HttpClient(clientEngine) {
install(JsonFeature) {
serializer = KotlinxSerializer(Json.nonstrict)
}
// addDefaultResponseValidation()
HttpResponseValidator{
validateResponse { response: HttpResponse ->
val statusCode = response.status.value
when (statusCode) {
in 300..399 -> throw RedirectResponseException(response)
in 400..499 -> throw ClientRequestException(response)
in 500..599 -> throw ServerResponseException(response)
}
if (statusCode >= 600) {
throw ResponseException(response)
}
}
handleResponseException { cause: Throwable ->
throw cause
}
}
}
我在我的服务器上返回 http 状态代码 401 错误以进行测试,所以我应该看到我的代码抛出一个 ClientRequestException 并且 validateResponse 确实被调用,但我从未在控制台和我的应用程序中看到任何异常在没有任何迹象的情况下停止。
这是我的电话
private suspend fun getDataForUrl(url:String, callback: (MyObject?) -> Unit){
val response = client.get<MyObject>(url)
callback(response)
}
调用方式
fun getData(callback: (MyObject?) -> Unit){
launch(dispatcher()){
getDataForUrl("$BASE_URL", callback)
}
}
当我用 try/catch 包围通话时
try{
val response = client.get<MyObject>(url)
catch(e:Exception){
}
我确实得到了异常,但我真的不喜欢它被捕获在这里而不是在我的代码的上层。
当周围没有 try/catch 时,为什么它会被吞没?
【问题讨论】:
-
dispatcher()到底是做什么的? -
@Lucho For android 就是这个
internal actual fun dispatcher(): CoroutineDispatcher = Dispatchers.IO -
好吧,我在 atm 看不到任何东西,但是您可以尝试删除验证器以检查它是否可以在没有它的情况下运行,然后让其余的(我相信 Ktor 默认会在 400、500 上抛出异常)系列,不确定300)。那它会扔给你吗?
-
我之前没有验证器,但仍然没有出现异常,我使用的是
addDefaultResponseValidation,这是我为验证器复制大部分代码的地方,但我仍然没有得到任何东西 -
我刚刚试了一下,得到了
FATAL EXCEPTION。所以我确信问题不是 Ktor,而且“非常”肯定它是关于你如何在这里运行你的协程。您使用 try/catch 看到它的原因是因为您仍在父协程上下文中实际捕获异常并打印它。因此,我对您的建议是,在运行基本上将在协程中运行的 MPP 代码时,请确保您从 Activity/fragment 中“启动”它,以便它一直“冒泡”,这意味着您从 Android 调用的函数是suspend.