Обработка ошибок перед подпиской на Observable - PullRequest
0 голосов
/ 04 апреля 2020

Как правильно обработать ошибку в следующей функции?

          this.userService.getUser(uid)
            .pipe(
              catchError(err => {
                this.router.navigate(['/sign-up']);
              })
            )
            .subscribe(user => {
              if (user) {
                this.store.dispatch(new UserActions.LoggedIn());
                this.router.navigate(['/']);
              }
            })
public getUser(uid: string): Observable<User> {
    const source = this.baseApolloService.query<{ uid: string }, User>(getUserQuery, (data) => data.getUser, { uid });
    return source;
  }

В настоящее время я получаю сообщение об ошибке:

Предоставлено «неопределенное», где ожидался поток

Что я сделал неправильно? Заранее спасибо за помощь.

Ответы [ 3 ]

1 голос
/ 04 апреля 2020

catchError должен возвращать поток в ответ. Это должно обработать ошибку и вернуть default value.

catchError((err) => {
  this.router.navigate(["/sign-up"]);
  // return something
  // of({data: "something"})
});

. В вашем случае вы можете обнаружить ошибку в конце:

this.userService.getUser(uid).subscribe(
  (user) => {
    if (user) {
      this.store.dispatch(new UserActions.LoggedIn());
      this.router.navigate(["/"]);
    }
  },
  (error) => {
    console.log(error);
    this.router.navigate(["/sign-up"]);
  }
);

Подробнее: https://rxjs-dev.firebaseapp.com/api/operators/catchError

1 голос
/ 04 апреля 2020

Я думаю, catchError ожидает поток observable, и он говорит, что я должен вернуть в случае ошибки на путь subscribe без ошибок. Для вашего случая я бы сделал эту обработку ошибок в subscribe.

this.userService.getUser(uid)
            .subscribe(user => {
              if (user) {
                this.store.dispatch(new UserActions.LoggedIn());
                this.router.navigate(['/']);
              }
            }, (error) => {
               console.log(error);
               this.router.navigate(['/sign-up']);
            })

Rx js catchError, требующих потока и документации: https://www.learnrxjs.io/learn-rxjs/operators/error_handling/catch

======================== Изменить ====================== ===== Я вижу, что вы хотите обработать ошибку перед подпиской, тогда да, вы должны предоставить поток для subscribe, но условие внутри if не будет выполняться, потому что мы вернем null.

Попробуйте:

import { of } from 'rxjs';
....
this.userService.getUser(uid)
            .pipe(
              catchError(err => {
                this.router.navigate(['/sign-up']);
                return of(null); // return null for the subscribe below
              })
            )
            .subscribe(user => {
              if (user) {
                this.store.dispatch(new UserActions.LoggedIn());
                this.router.navigate(['/']);
              }
            })

Я думаю, что оба пути хороши.

0 голосов
/ 04 апреля 2020

Это поможет тебе.

 this.userService.getUser(uid)
   .pipe(catchError(err => {
       this.handleError(err);
       return of<any>({ isSuccess: false, error: err });
 }).subscribe(user => {
       //your code
   })

Если возникает ошибка, то в нее включается logi c catchError. Оператор catchError принимает ошибку и передает ее в функцию обработки ошибок. CatchError - это просто функция, которая принимает входную Observable и выводит Output Observable. Ожидается, что эта функция возвратит Observable, который станет заменой Observable для потока, который только что допустил ошибку. Функция обработки ошибок приведена ниже.

 private handleError(error: HttpErrorResponse): void {
        if (error.error instanceof ErrorEvent) {
            // A client-side or network error occurred. Handle it accordingly.
        } else {
            // The backend returned an unsuccessful response code.
            // The response body may contain clues as to what went wrong,
        }
    }
...