【问题标题】:How to return an exception from a method called with .await()如何从使用 .await() 调用的方法返回异常
【发布时间】:2023-03-25 15:24:01
【问题描述】:

我正在使用新的 google services coroutines 扩展函数来实现从异步调用返回异常

suspend fun saveUserToken(user: User): Resource<Boolean> {
    val result = FirebaseInstanceId.getInstance().instanceId.await()
    user.deviceToken = result.token
    FirebaseFirestore.getInstance().collection("user").document(user.uid).set(user).await()
    return Resource.success(true)
}

这里我做了两个异步操作,第一个检索用户设备令牌,第二个将设备令牌+用户数据存储到 Firestore 中

现在我的问题是。

如果一个被抛出,我如何知道或从这两种方法返回异常?

由于是一个Task,异常应该以同一个对象的形式返回,我已经阅读了.await()方法,看看它是如何处理异常的

public suspend fun <T> Task<T>.await(): T {
    // fast path
    if (isComplete) {
        val e = exception
        return if (e == null) {
            if (isCanceled) {
                throw CancellationException("Task $this was cancelled normally.")
            } else {
                result
            }
        } else {
            throw e
        }
    }

    return suspendCancellableCoroutine { cont ->
        addOnCompleteListener {
            val e = exception
            if (e == null) {
                if (isCanceled) cont.cancel() else cont.resume(result)
            } else {
                cont.resumeWithException(e)
            }
        }
    }
}

这里有两种类型的异常,一种是调用它的任务异常(这是我想在我的第一个代码块中捕获的异常),第二种是取消协程时触发的 CancellationException

【问题讨论】:

    标签: android firebase kotlin kotlin-coroutines


    【解决方案1】:

    只需像使用任何其他代码一样使用 try/catch:

    try {
        val result = FirebaseInstanceId.getInstance().instanceId.await()
        user.deviceToken = result.token
        FirebaseFirestore.getInstance().collection("user").document(user.uid).set(user).await()
        return Resource.success(true)
    }
    catch (e: Exception) {
        // handle the error here
    }
    

    或者您可以将 try/catch 放在对 saveUserToken 的调用周围。无论哪种情况,如果 try catch 中的挂起乐趣产生错误,您的 catch 就会触发。

    我建议阅读exception handling with Kotlin coroutines 上的文档。

    【讨论】:

    • 谢谢道格,最后一个问题,如果我在这个方法中抛出了多个异常,应该可以将它们全部包装在 Exception 中,或者我应该在那里捕获多个带有确切异常名称的异常?
    • 取决于您需要了解或处理每个异常的内容。做任何适合你的事情,就像任何其他尝试/捕捉一样。
    • 谢谢,它只需要阻止用户并发出友好的消息,我认为有异常就可以了,因为如果两者之一失败,另一个没有完成,那时我只会抛出 1 个异常
    • 它给用户一个友好的消息,我将错误记录到 Firebase crashlytics 以更好地了解正在发生的事情
    猜你喜欢
    • 2021-05-11
    • 2020-05-03
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2018-04-27
    • 1970-01-01
    相关资源
    最近更新 更多