嵌套 httpClient 调用并判断哪个失败?

Nest httpClient calls and tell which one failed?

我有一个组件有点像底部的伪代码片段。

我需要修改 onDeployForTesting() 以便它在调用 myService.deployForTesting() 之前调用 myService.save()。我一直在研究嵌套的 Observable 和对 httpClient 的嵌套调用,但我永远无法判断哪个 Observable 失败了(如果有的话)。我需要知道这一点,以便我可以继续设置通知。

问题

如何嵌套两个(或更多)httpClient 请求,并查看链中的哪一个失败(以 RxJS 方式)?

我试过的

onSaveAndDeployForTesting() {
    this.myService
        .save(arg1)
        .pipe(
            concatMap(  // also tried: switchMap, mergeMap
                () => this.myService.deployForTesting(arg2),
            ),
        )
        .subscribe(
            console.info,
            console.error,  // this gives a very generic error with no pointer to which Observable actually failed
            console.info,
        );
}

现有代码

class MyClass {
    // other code

    onSave() {
        this.myService.save(arg1)
            .subscribe(
                (data) => {
                    this.notificationService.set({
                        type: NotificationType.SUCCESS,
                        title: 'Success',
                        description: 'Lorem ipsum dolor sit amet',
                    });
                },
                (err) => {
                    if (err.errorCode === 409) {
                        this.notificationService.set({
                            type: NotificationType.WARNING,
                            title: 'Save Conflict',
                            description: 'Lorem ipsum dolor sit amet',
                        });
                    } else {
                        this.notificationService.set({
                            type: NotificationType.ERROR,
                            title: 'Error',
                            description: 'Lorem ipsum dolor sit amet',
                        });
                    }
                },
            );
    }

    onDeployForTesting(arg1) {
        this.myService.deployForTesting(arg1)
            .subscribe(
                (data) => {
                    if (data.status === 207) {
                        this.notificationService.set({
                            type: NotificationType.WARNING,
                            title: 'Unable to deploy configuration',
                            description: 'Lorem ipsum dolor sit amet',
                        });
                    } else {
                        this.notificationService.set({
                            type: NotificationType.SUCCESS,
                            title: 'Success',
                            description: 'Lorem ipsum dolor sit amet',
                        });
                    }
                },
                (err) => {
                    this.notificationService.set({
                        type: NotificationType.ERROR,
                        title: 'Error',
                        description: 'Lorem ipsum dolor sit amet',
                    });
                },
            );
    }
}

class MyService {
    // other code

    save(data) {
        return this.http.put('/my/save/url', data);
    }

    deployForTesting(data) {
        return this.http.post('/my/deploy/url', data);
    }
}

您可以使用 RxJS catchError。尝试以下

import { throwError, of, EMPTY } from 'rxjs';
import { catchError, concatMap } from 'rxjs/operators';

onSaveAndDeployForTesting() {
  this.myService.save(arg1).pipe(
    catchError(saveError => this.handleSaveError(saveError)),
    concatMap(() => this.myService.deployForTesting(arg2).pipe(
      catchError(deployError => this.handleDeployError(deployError))
    ))
  )
  .subscribe(
    console.info,
    console.error,
    console.info,
  );
}

handleSaveError(error) {
  // handle error from `save()` call
  return EMPTY;      // also `throwError()` or `of()`
}

handleDeployError(error) {
  // handle error from `deployForTesting()` call
  return EMPTY;      // also `throwError()` or `of()`
}

记住 return 来自 catchError 的可观察对象。