HTTPInterceptor в angular 7 ведет себя странно - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть очень простой перехватчик, который перехватывает ошибки и печатает вывод на консоль:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
        catchError((error: HttpErrorResponse) => {
            if (error.status == 401) {
                console.log("Error 401", error);
            }
            else if (error.status == 404) {
                console.log("Error 404", error);
            }
            else if (error.status == 0) {
                console.log("Unknown error", error);
                sendRequestAgain();
            } else{
               // do nothing
            }
            return throwError(error)
        })
    );
}

Проблема в том, что когда я получаю error.status==0, он отлично работает в первый раз, и запросотправлено снова (с sendRequestAgain()), но когда запрос завершается неудачно во второй раз, ошибка перехватывается правильно, но элемент управления не переходит в блок else if (error.status == 0) {.Вместо этого он идет вниз к блоку else.Я распечатал ошибку, и она одинакова оба раза.Даже точка останова на else if (error.status == 0) { не попадает во второй раз, что совершенно странно.

Есть идеи?

1 Ответ

1 голос
/ 26 сентября 2019

Вы можете попробовать объединить карту и проверить, является ли ошибка ошибкой, которую вы хотите повторить, в этом случае я использую 404, и если это так, вы устанавливаете таймер rxjs до обработки следующего запроса и, наконец, после использованияОператор берет, чтобы установить, сколько раз повторить попытку подключения.Если ошибка не является ошибкой, которую вы хотите повторить, то просто повторно ее обработайте и обработайте, как будто ничего не произошло раньше.

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
} from '@angular/common/http';

import {Observable, throwError, timer} from 'rxjs';
import {catchError, mergeMap, retryWhen, take} from 'rxjs/operators';

@Injectable()
export class EnsureHttpsInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      retryWhen(errors => {
        return errors
          .pipe(
            mergeMap(error => error.status === 404 ? timer(5000) : throwError(error)),
            take(2)
          );
      }),
      catchError((error: HttpErrorResponse) => {

        switch (error.status) {
          case 401:
            console.log('Error 401', error);
            break;
          case 404:
            console.log('404', error);
            break;
          default:
            return throwError(error);
        }

      })
    );
  }
}
...