Как правильно выбросить исключение rxjs?

#angular #rxjs

#angular #rxjs

Вопрос:

Есть щелчок события потока:

 this.markAsReadClick
            .pipe(
                concatMap(() =>
                    this.documentsRepository.selectedDocumentsReestrIds$.pipe(
                        take(1),
                        tap((ids: number[]) => {
                            if (!ids.length) throw throwError('Error');
                        }),
                      
                        concatMap((ids: number[]) => ...
 

попытка создать исключение, чтобы предотвратить выполнение concatMap:

 if (! ids.length) throw throwError ('Error');
 

При возникновении ошибки — this.markAsReadClick завершается. Как этого избежать?

Полный код:

 this.markAsReadClick
            .pipe(
                concatMap(() =>
                    this.documentsRepository.selectedDocumentsReestrIds$.pipe(
                        take(1),
                        tap((ids: number[]) => {
                            if (!ids.length) throw throwError('Err');
                        }),
                        indicate(this.markAsReadloading$),
                        concatMap((ids: number[]) =>
                            this.confirmDialogsService.open({ title: 'Подтверждение операции', text: 'Вы уверены?' }).pipe(
                                filter(Boolean),
                                concatMap(() =>
                                    this.documentsRepository.markAsPrinted(ids).pipe(
                                        handleResponseMessage(this.messageService),
                                        catchError((error) => of(error)),
                                    ),
                                ),
                            ),
                        ),
                    ),
                ),
                catchError((error) => of(error)),
            )

            .subscribe((response) => {
                console.log(response);
                if (response instanceof Error) {
                    this.messageService.showMessage('', response.message, 'warning');
                    return;
                }
                this.router.navigate(['documents'], { queryParams: { t: new Date().getTime() } });
            });
 

Ответ №1:

throwError является ли обычная ошибка обернутой Observable, предназначенной для операторов, которые должны возвращать наблюдаемые значения (например switchMap , contactMap , и т. Д.), Для tap operator Вы должны выдавать обычную ошибку, а не наблюдаемую:

 tap((ids: number[]) => {
   if (!ids.length) throw new Error('Err');
}),
 

Выдав ошибку внутри contactMap (внутреннего потока), вы должны обработать ее там (используя cathError ), чтобы избежать завершения внешнего потока:

 concatMap(() =>
  this.documentsRepository.selectedDocumentsReestrIds$.pipe(
    take(1),
    tap((ids: number[]) => {
      if (!ids.length) throw throwError('Err');
    }),
    indicate(this.markAsReadloading$),
    concatMap((ids: number[]) =>
        ...
    ),
    catchError(x => of(x) // <== handle inner stream errors
  )
)