【问题标题】:RxJava Single and Room Error handling ProblemRxJava Single 和 Room 错误处理问题
【发布时间】:2018-10-28 02:41:19
【问题描述】:

我遇到了关于 Room 和 RxJava Single 返回空数据库的问题。 我知道我的数据库是空的,所以我希望在触发时得到一个空的返回

@Query("SELECT * FROM Times WHERE timestamp = :timestamp")
fun getTimes(timestamp: String): Single<Times>

问题是当我如下调用这个函数时

timeDao.getTimes("1398332113")
       .observeOn(AndroidSchedulers.mainThread())
       .subscribeOn(Schedulers.io())
       .doOnError { Log.e("Single", "Returned null") }
       .doOnSuccess { result -> times = result}
       .subscribe()

订阅者确实在调用doOnError 方法

E/Single:返回 null

但仍然返回异常并崩溃

W/System.err:io.reactivex.exceptions.OnErrorNotImplementedException: 查询返回空结果集:SELECT * FROM Times WHERE timestamp = ?

我在 StackOverflow 上看到了很多类似的问题,但找不到答案。我做错了什么?

【问题讨论】:

  • doOn... 运算符是副作用运算符,它们不是订阅者。您应该在订阅方法中实现onSuccessonError。您应该考虑改用Maybe - 一个单一的,如前所述是成功或错误,因此如果您有空结果将出错,除非这是需要的(恕我直言 onError 应该只用于不可恢复的错误,而不是作为全部可预防的问题)。

标签: android exception-handling rx-java android-room rx-android


【解决方案1】:

首先解决您的问题。由于版本 2.1.0-alpha01 Room 支持 Maybe 返回类型,这非常适合建模您的问题。

来自documentation

Maybe 使用以下顺序协议运行:onSubscribe (onSuccess | onError | onComplete)?

当您的项目在数据库中时:onSuccess 将与数据一起调用。如果数据库为空onComplete 将被调用。 onError 不言自明。

将 Dao 类中的 Single 替换为 Maybe 即可。

补充说明:

timeDao.getTimes("1398332113")
       .observeOn(AndroidSchedulers.mainThread())
       .subscribeOn(Schedulers.io())
       .doOnError { Log.e("Single", "Returned null") }
       .doOnSuccess { result -> times = result}
       .subscribe()

doOnError

doOnError 将在出现 en 错误时执行 lambda,但它仍会沿链发出错误。您的程序崩溃是因为它不处理错误(subscribe() 为空)。

您可以使用subscribe({/* doing nothing for success */}, {e -&gt; Log.e("TAG", "Empty DB")}) 来防止崩溃。

默认值

如果目标是在数据库为空的情况下返回一些默认值,那么您将需要使用onErrorReturn 以便链继续。请查看this blog post 了解更多信息。

空值

默认值不能为空,Reactive Streams 规范(RxJava2 实现)不支持空值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 2018-10-14
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多