首页 > 解决方案 > Try 块抛出异常,但 catch 块没有捕获它

问题描述

我正在使用谷歌登录,但出现异常。但是,看起来我无法抓住它。

我有以下代码:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            RC_SIGN_IN -> {
                val task = try{
                    GoogleSignIn.getSignedInAccountFromIntent(data)
                } catch (e: ApiException) {
                    Log.d("EXCEPTION", e.message)
                    when(e.statusCode) {
                        12501 -> return
                        else -> {
                            e.printStackTrace()
                            return
                        }
                    }
                }
...

从 Logcat 我可以看到,这ApiException是正确的异常捕获:

在此处输入图像描述

它绝对是我要抓住的一个:

在此处输入图像描述

起初我认为直接分配val task = try...可能是由于某种原因造成的,所以我相应地更改了我的代码并尝试了这个:

var task: Task<GoogleSignInAccount>?
try{
    task = GoogleSignIn.getSignedInAccountFromIntent(data)
} catch (e: ApiException) {
    Log.d("EXCEPTION", e.message)
    when(e.statusCode) {
       12501 -> task = null
       else -> {
           e.printStackTrace()
           task = null
       }
    }
}

不过,同样的行为。所以我想可能抛出另一个异常,所以我添加了另一个 catch 块:

var task: Task<GoogleSignInAccount>?
try{
    task = GoogleSignIn.getSignedInAccountFromIntent(data)
} catch (e: ApiException) {
    Log.d("EXCEPTION", e.message)
    when(e.statusCode) {
       12501 -> task = null
       else -> {
           e.printStackTrace()
           task = null
       }
    }
} catch (e: Exception) {
    Log.d("EXCEPTION", e.message)
    task = null
}

仍然是相同的行为。我发现这段代码在每一步都有断点,但它完全忽略了 catch 块。我停在 try 块:

在此处输入图像描述

但如果我继续,下一步将在我的 try-catch 块之外。

在此处输入图像描述

有人可以解释这种行为吗?

标签: androidkotlingoogle-signin

解决方案


就在我问这个问题的时候,我意识到了一件事:

catch 块被忽略,因为 try 块并没有真正抛出异常。

task对象已设置,并且它是保存异常的对象。当task以后像这样使用对象时:val account = task.getResult(ApiException::class.java)那么这就是实际引发异常的地方。至少这是我在这里所期望的。异常本身基本上在稍后的时间点被捕获、保存和抛出,但是使用旧的堆栈跟踪......

不能 100% 确定它的内部工作原理,但这就是我从 logcat 和我的代码中可以看出的。

因此,我没有尝试捕获,而是手动处理了异常:

val task = GoogleSignIn.getSignedInAccountFromIntent(data)
if(task.exception != null) {
    val e = task.exception as? ApiException
    if(e != null) {
        when(e.statusCode) {
            12501 -> return
            else -> {
                e.printStackTrace()
                return
            }
        }
    } else {
        task.exception?.printStackTrace()
    }
    return
}

推荐阅读