Global ErrorHandler не работает после реализации catchError в эффекте ngrx - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь обработать ошибку в моем угловом приложении, но глобальный обработчик ошибок не работает.

Я использую ngrx для управления состоянием и имею глобальный обработчик ошибок в моем угловом приложении.Я использую оператор catchError для обработки ошибки в ngrx / effect, как предложено здесь .Но теперь я не могу использовать глобальный обработчик ошибок, и мне нужно перехватывать ошибки в каждом эффекте.

// ErrorHandler

handleError(error: Error | HttpErrorResponse) {
  const router = this.injector.get(Router);
  console.error("Error intercepted.", error);
  this.spinner.hide();
  if (error instanceof HttpErrorResponse) {
     if (!navigator.onLine) {
        this.showError('No internet connection');
     } else {
        if (error.error.message) {
            this.showError(`${error.error.message}`);
        } else {
            this.showError(`${error.status} - ${error.message}`);
        }
     }
  } else {
     this.showError("Unknow error.");
     router.navigate(['/dashboard']);
    }
}

// ngrx эффекты

export class EffectError implements Action {
    readonly type = '[Error] Effect Error';
}

@Effect()
UserAuth: Observable < Action > = this.actions.pipe(
  ofType(SigninActions.AUTHENTICATE_USER),
  switchMap((action: SigninActions.AuthenticateUser) =>
    this.signinService.signin(action.payload.emailAddress, action.payload.password).pipe(
        map((loginContext: LoginContext) => {
            console.log("LOGIN_CONTEXT", loginContext);
            return new SigninActions.AuthenticateUserSuccess(loginContext)
        }),
        //CatchError
        catchError(() => of(new EffectError()))
    )
   )
);

Я использую оператор catchError, чтобы эффект не прерывался при возникновении ошибки, и глобальный обработчик ошибок для отображения различных сообщений об ошибках.

1 Ответ

0 голосов
/ 19 июня 2019

Проблема в том, что catchError в @Effect будет проглотить ошибку, и она не будет распространяться обратно к ErrorHandler.

Вы можете найти много постово том, как это сделать, но если подвести итог, то вам нужно реализовать HttpInterceptor и использовать catchError для обработки ошибок, отправленных обратно HttpHandler:

import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError(error => {
        if (error instanceof HttpErrorResponse) {
          // check for internet connection
          if (!navigator.onLine) {
            this.showError('No internet connection');
          }
          // handle HTTP errors
          switch (error.status) {
            case 401:
              // do something
              break;
            case 403:
              // do something else
              break;
            default:
              // default behavior
          }
        }
        // need to rethrow so angular can catch the error
        return throwError(error);
      }));
  }
}

Тогда, конечно, нене забудьте представить свою реализацию перехватчика ошибок, используя токен инжекции HTTP_INTERCEPTORS в вашем AppModule:

import { HTTP_INTERCEPTORS } from '@angular/common/http';

...

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
],

Таким образом, вы можете обрабатывать ошибки, комбинируя оба ...

  • ErrorHandler для ошибок на стороне клиента (javascript, angular, ...)
  • HttpInterceptor для HTTP-запросов

Вот хороший пост о различных способах обработки ошибок в angular:
https://blog.angularindepth.com/expecting-the-unexpected-best-practices-for-error-handling-in-angular-21c3662ef9e4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...