RxJS повторите попытку, а затем ошибка catchError не работает

#error-handling #rxjs #observable #nestjs

#обработка ошибок #rxjs #наблюдаемый #nestjs

Вопрос:

У меня наблюдаемый:

 public updateThingName(name: string, thingId: number): Observable<any> {
    console.log('attempting rename');
    return this.http
        .put(
          `${this.thingApi}/projects/${thingId}`, 
          { name },
          this.options,
      ).pipe(
          map(response => response.data.id)
      );
}
 

вызывается как часть более длинной цепочки:

     return this.projectService.getProject(id).pipe(
            switchMap(prevProjectData => {
                return this.projectService.updateProject(id, data).pipe(
                    map(newProjectData => ({prevProjectData, newProjectData}))
                )
            }),
            switchMap(({prevProjectData, newProjectData}) => {
                return this.thingService.updateThingName(newProjectData.title, newProjectData.thingId)
                  .pipe(retry(5),catchError(err => {
                      return this.projectService.revertProjectUpdate(err, prevProjectData);
                }))
            }),
            tap(() => { ... save to logs only when successful ... })
        );
 

Я хочу попытаться что-то переименовать, если это не удается, повторите попытку 5 раз, если все еще не удается, затем перехватите ошибку, отмените предыдущие изменения и выдайте окончательную ошибку в функции возврата. Возврат и отправка ответа об ошибке обратно во внешний интерфейс работает нормально, но независимо от того, куда я помещаю retry(5) , я вижу только начальное console.log('attempting rename'); значение в журналах.

Я пропустил повторную попытку? Как мне заставить это работать?

Это внутренний код на NestJS, поэтому я не обрабатываю окончательные аспекты подписки напрямую, если это имеет значение.

Спасибо!

Ответ №1:

Это должно быть правильно. Метод вызывается один раз, но он пытается повторно подписаться несколько раз. Вы должны быть в состоянии увидеть это, если вы регистрируете сообщение при каждой подписке:

 public updateThingName(name: string, thingId: number): Observable<any> {
  return defer(() => {
    console.log('attempting rename');
    return this.http
      .put(
        `${this.thingApi}/projects/${thingId}`, 
        { name },
        this.options,
    ).pipe(
        map(response => response.data.id)
    );
  )};
}
 

Комментарии:

1. Да, теперь отображаются журналы для количества попыток. пенни только что упал на это, это только повторная попытка наблюдаемого, а не метода. обернув его в defer и вернув, я теперь вижу журнал, поскольку он является частью возвращаемого наблюдаемого