按照讨论的主题here。我正在使用Clean Architecture编写Android应用程序。我有一个Interactor负责检索用户的Feed数据。流程是这样的:
我的FeedCache和PendingPostCache都适用于Sqlite。如果出现问题,Botch可以抛出DBExceptions。对于服务器端发出请求的FeedRepository也可以在出现错误时抛出异常(ServerSideException)。
以下是我的Interactor的完整代码:
mFeedRepository.getFeed(offset, pageSize) //Get items from the server-side
.onErrorResumeNext(mFeedCache.getFeed(userSipid)) //If something goes wrong take it from cache
.mergeWith(mPendingPostCache.getAllPendingPostsAsFeedItems(user)) //Merge the response with the pending posts
.subscribe(new DefaultSubscriber<List<BaseFeedItem>>() {
@Override
public void onNext(List<BaseFeedItem> baseFeedItems) {
callback.onFeedFetched(baseFeedItems);
}
@Override
public void onError(Throwable e) {
if (e instanceof ServerSideException) {
//Handle the http error
} else if (e instanceof DBException) {
//Handle the database cache error
} else {
//Handle generic error
}
}
});
我不喜欢那些实例。我正在考虑创建一个自定义订阅者,称为MyAppSubscriber,它实现onError方法,进行那些实例比较,并执行一些名为onServerSideError(),onDBError()的方法。这样代码就会变得更清晰,我可以节省编写样板代码的实例。有人更好地了解如何处理这个问题?某种方法可以避免自定义订阅者?
答案 0 :(得分:3)
只需使用构图:
public <T,E> Function<Throwable, Observable<T>> whenExceptionIs(Class<E> what, Function<E, Observable<T>> handler) {
return t -> {
return what.isInstance(t) ? handler.apply(what.cast(t)) : Observable.error(t);
};
}
然后你正常使用它:
Observable.from(...).flatMap(...)
.onErrorResumeNext(whenExceptionIs(ServerSideException.class, e-> Observable.empty()))
.onErrorResumeNext(whenExceptionIs(DBException.class, e-> ...))
你甚至可以用一种方法抽象出所有这些:
public <T> Transformer<T, T> errorHandling() {
return src -> src
.onErrorResumeNext(whenExceptionIs(ServerSideException.class, e-> Observable.empty()))
.onErrorResumeNext(whenExceptionIs(DBException.class, e-> ...));
}
Observable.from(...).flatMap(...)
.compose(errorHandling())
.subscribe();