如何解决每当创建异常实例时,suspendCoroutine都会使应用程序崩溃
我有一个suspend fun
,如果一切正常,它应该返回Result.success
;如果发生错误或设置了Result.failure
标志,则返回"isBlocked"
。
override suspend fun userData(userId: String) = suspendCoroutine<ResultData> { continuation ->
userReference(userId).get().addOnSuccessListener { snapshot ->
val data = snapshot.data ?: mutableMapOf()
replaceTimestampWithDate(data)
if ((data["isBlocked"] as? Boolean) == true) {
continuation.resume(Result.failure(Exception()))
} else
continuation.resume(Result.success(data))
}.addOnFailureListener {
continuation.resume(Result.failure(it))
}
}
但是,只要创建Exception()
的实例,应用就会崩溃。
java.lang.Exception
at co.thoron.langmate.data.providers.DataProvider$userData$$inlined$suspendCoroutine$lambda$1$1$1.onSuccess(DataProvider.kt:72)
at co.thoron.langmate.data.providers.DataProvider$userData$$inlined$suspendCoroutine$lambda$1$1$1.onSuccess(DataProvider.kt:29)
at com.google.android.gms.tasks.zzn.run(com.google.android.gms:play-services-tasks@@17.1.0:4)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at com.google.android.gms.internal.tasks.zzb.dispatchMessage(com.google.android.gms:play-services-tasks@@17.1.0:6)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
我不明白为什么会这样,因为我什至没有抛出异常。我尝试将其包装在try { ... } catch { ... }
,contextCoroutine
中,但得到的结果仍然相同。我什至不希望协程“看到”异常,我只想通过Result
类型传递它。
解决方法
我认为您应该尝试使用包装器类,而不是像这样传递异常。它对我来说效果非常好,我的代码也得到了显着改善。这是您如何做的参考。 https://phauer.com/2019/sealed-classes-exceptions-kotlin/
,按照Tensky的建议,我最终创建了自己的Result
类型的实现。下面是我创建的。稍后,我将尝试清理它并添加更多的失败原因,但目前看来效果很好。
sealed class Result<T>(val value: T?,val failureReason: String?) {
class Success<T>(val valueData: T) : Result<T>(valueData,null)
sealed class Failure<T>(failureReason: String) : Result<T>(null,failureReason) {
class Unknown<T>(val failureReasonData: String) : Failure<T>(failureReasonData)
companion object {
fun <T> unknown(failureReason: String) = Failure.Unknown<T>(failureReason)
operator fun <T>invoke(exception: Throwable) = when (exception) {
else -> Failure.Unknown<T>(exception.toString())
}
}
}
companion object {
fun <T>success(value: T) = Success(value)
}
fun valueOrDefault(defaultValue: T) = value ?: defaultValue
inline fun <R>map(transform: (value: T) -> R): Result<R> = when (this) {
is Success -> Result.success(transform(valueData))
is Failure.Unknown -> Failure.unknown(failureReasonData)
}
inline fun <R>mapResult(transform: (value: T) -> Result<R>): Result<R> = when (this) {
is Success -> transform(valueData)
is Failure.Unknown -> Failure.unknown(failureReasonData)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。