Programing

이제 droughError(오류)는 사용되지 않지만 새로운 오류(HttpErrorResponse)는 없다.

c10106 2022. 3. 29. 21:32
반응형

이제 droughError(오류)는 사용되지 않지만 새로운 오류(HttpErrorResponse)는 없다.

보아하니throwError(error)지금은 더 이상 사용되지 않는다.VS Code의 IntelliSense는throwError(() => new Error('error').new Error(...)현악만 받아들이다내 것을 깨뜨리지 않고 교체할 수 있는 올바른 방법은 무엇일까?HttpErrorHandlerService ?

http-htp.properties.ts

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpErrorResponse,
  HttpResponse,
  HttpHeaders
} from '@angular/common/http';
import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';

import { HttpErrorHandlerService } from '@core/services';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  private readonly APP_XHR_TIMEOUT = 6000;

  constructor(private errorHandlerService: HttpErrorHandlerService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(this.performRequest(request)).pipe(
      timeout(this.APP_XHR_TIMEOUT),
      map((event: HttpEvent<any>) => this.handleSuccessfulResponse(event)),
      catchError((error: HttpErrorResponse) => this.processRequestError(error, request, next)),
      finalize(this.handleRequestCompleted.bind(this))
    );
  }

  private performRequest(request: HttpRequest<any>): HttpRequest<any> {
    let headers: HttpHeaders = request.headers;
    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
    return request.clone({ headers });
  }

  private handleSuccessfulResponse(event: HttpEvent<any>): HttpEvent<any> {
    if (event instanceof HttpResponse) {
      event = event.clone({ body: event.body.response });
    }
    return event;
  }

  private processRequestError(
    error: HttpErrorResponse,
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    console.log('http error response');

    if ([401].includes(error.status)) {
      return throwError(error);
    }

    this.errorHandlerService.handle(error);

    return throwError(error);
  }

  private handleRequestCompleted(): void {
    // console.log(`Request finished`);
  }
}

import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';

import { MessageService } from 'primeng/api';
import { TimeoutError } from 'rxjs';

/**
 * Shows a user-friendly error message when a HTTP request fails.
 */
@Injectable({
  providedIn: 'root'
})
export class HttpErrorHandlerService {
  constructor(private messageService: MessageService) {}

  handle(error: Error | HttpErrorResponse) {
    if (error instanceof TimeoutError) {
      return this.openDialog('error', `Няма връзка до сървъра.`);
    }

    if (error instanceof HttpErrorResponse && error.error && error.error.message) {
      return this.openDialog('error', error.error.message);
    }

    if (error instanceof Error) {
      switch (error.message) {
        default:
          return this.openDialog('error', `An unknown error occurred`);
      }
    }

    // Generic HTTP errors
    switch (error.status) {
      case 400:
        switch (error.error) {
          case 'invalid_username_or_password':
            return this.openDialog('error', 'Невалидно потребителско име или парола');
          default:
            return this.openDialog('error', 'Bad request');
        }

      case 401:
        return this.openDialog('error', 'Ще трябва да се логнете отново');

      case 403:
        return this.openDialog('error', `You don't have the required permissions`);

      case 404:
        return this.openDialog('error', 'Resource not found');

      case 422:
        return this.openDialog('error', 'Invalid data provided');

      case 500:
      case 501:
      case 502:
      case 503:
        return this.openDialog('error', 'An internal server error occurred');

      case -1:
        return this.openDialog(
          'error',
          'You appear to be offline. Please check your internet connection and try again.'
        );

      case 0:
        return this.openDialog('error', `CORS issue?`);

      default:
        return this.openDialog('error', `An unknown error occurred`);
    }
  }

  private openDialog(severity: string, message: string) {
    if (message?.trim()) {
      this.messageService.add({
        key: 'interceptor',
        severity: severity,
        summary: 'Информация',
        detail: message,
        life: 3000
      });
    }
  }
}

auth.properties.ts

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpErrorResponse
} from '@angular/common/http';
import {
  BehaviorSubject,
  catchError,
  EMPTY,
  filter,
  finalize,
  Observable,
  switchMap,
  take,
  throwError
} from 'rxjs';

import { AuthService } from '@core/services';
import { AuthResponse } from '@core/types';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  private refreshTokenInProgress: boolean;
  private refreshToken$ = new BehaviorSubject<AuthResponse | null>(null);

  constructor(private authService: AuthService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next
      .handle(this.performRequest(request))
      .pipe(
        catchError((error: HttpErrorResponse) => this.processRequestError(error, request, next))
      );
  }

  private performRequest(request: HttpRequest<any>): HttpRequest<any> {
    const accessToken = this.authService.getAccessToken();

    let headers = request.headers;
    if (accessToken) {
      headers = headers.set('Authorization', `Bearer ${accessToken}`);
    }

    return request.clone({ headers });
  }

  private processRequestError(
    error: HttpErrorResponse,
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    console.log('auth interceptor called');

    if (
      error instanceof HttpErrorResponse &&
      error.status === 401 &&
      this.authService.isSignedIn()
    ) {
      return this.refreshToken(request, next);
    }

    return throwError(error);
  }

  private refreshToken(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('refresh token in auth.interceptor called');

    // in case the page consists of more than one requests
    if (!this.refreshTokenInProgress) {
      this.refreshToken$.next(null);
      this.refreshTokenInProgress = true;

      return this.authService.refreshToken().pipe(
        switchMap((response) => {
          if (response) {
            this.refreshToken$.next(response);
            return next.handle(this.performRequest(request));
          }

          this.authService.signOut();
          return throwError(() => new Error("RefreshTokenFailed"));
        }),
        catchError((error) => {
          this.authService.signOut();
          return throwError(error);
        }),
        finalize(() => (this.refreshTokenInProgress = false))
      );
    } else {
      // wait while getting new token
      return this.refreshToken$.pipe(
        filter((result) => result !== null),
        take(1),
        switchMap(() => next.handle(this.performRequest(request)))
      );
    }
  }
}

대신 다음과 같이 하십시오.

    catchError((error) => {
      this.authService.signOut();
      return throwError(error);
    }),

이것을 시도해 볼 수 있다.

    catchError((error) => {
      this.authService.signOut();
      return throwError(() => error);
    }),

철저하게 테스트할 수는 없었지만 간단한 시도는 효과가 있는 것 같았다.

이것은 간단한 테스트였습니다(RxJS v7.2 사용):

서비스

  getProducts(): Observable<IProduct[]> {
    return this.http.get<IProduct[]>(this.productUrl)
      .pipe(
        tap(data => console.log('All: ', JSON.stringify(data))),
        catchError(this.handleError)
      );
  }

  private handleError(err: HttpErrorResponse): Observable<never> {
    // just a test ... more could would go here
    return throwError(() => err);
  }

에 유의하십시오.err여기는 유형이다.HttpErrorResponse.

구성 요소

  ngOnInit(): void {
    this.sub = this.productService.getProducts().subscribe({
      next: products => {
        this.products = products;
        this.filteredProducts = this.products;
      },
      error: err => this.errorMessage = err.message
    });
  }

여기서 나는 그 물건을 되찾을 수 있었다.message오류 응답의 속성 및 UI에 표시.

이것이 너에게 효과가 있는지 내게 알려줘.

간단히 사용:

return new Error(message);

불필요한 사용

return throwError(() => new Error(message));

여기에서 예제를 참조하십시오.

참조URL: https://stackoverflow.com/questions/68655492/throwerrorerror-is-now-deprecated-but-there-is-no-new-errorhttperrorresponse

반응형