我有一个flatMap,它运行一系列HTTP调用来注册用户,检索其个人资料和其他一些东西。我想根据错误发生在onError的哪个阶段,用特定的错误消息通知subscription中的flatMap。也许注册成功,但是检索创建的配置文件没有成功。我该如何做到这样,一旦发生错误,我的flatMap就会停止所有后续调用?

这是我的ObservableSubscription的一些伪代码:

Retrofit.registerUser()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .flatMap({
            return Retrofit.authenticate();
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .flatMap({
            return Retrofit.retrieveProfile()
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .flatMap({
            return Retrofit.retrieveOtherStuff()
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1 {

        }, new Action1<Throwable>() {
          // I would like to display the error to my user here
        }));

最佳答案

至少有两种方法可以做到这一点:


使用doOnError运算符:

Retrofit.registerUser()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnError(error -> {
        showRegistrationFailedError(error);
    })
    .flatMap({
        return Retrofit.authenticate().doOnError(error -> {
            showAuthenticationFailedError(error);
        });
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1 {

    }, new Action1<Throwable>() {
      // do nothing here. all errors are already handled in doOnError methods
    }));

使用onErrorResumeNext运算符:

Retrofit.registerUser()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onErrorResumeNext(error -> {
        return Observable.error(new RegistrationFailedException(error));
    })
    .flatMap({
        return Retrofit.authenticate().onErrorResumeNext(error -> {
            return Observable.error(new AuthenticationFailedException(error))
        });
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(value -> {

    }, error -> {
        if (error instanceof RegistrationFailedException) {
            showRegistrationFailedError(error);
        }

        if (error instanceof AuthenticationFailedException) {
            showAuthenticationFailedError(error);
        }
    }));

10-07 19:15
查看更多