Saltar al contenido

Manejo de errores Http en Angular 6

Hola, hemos encontrado la solución a lo que buscas, deslízate y la encontrarás más abajo.

Solución:

Para la solicitud de XHR, debe usar un Interceptor

Este es el que utilizo para agregar JWT a los encabezados y para manejar algunos errores de respuesta:

import Injectable from '@angular/core';
import 
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor, HttpErrorResponse
 from '@angular/common/http';
import AuthService from '../service/auth.service';
import Observable, of from 'rxjs';
import Router from "@angular/router";
import catchError from "rxjs/internal/operators";

@Injectable()
export class TokenInterceptor implements HttpInterceptor 

  constructor(public auth: AuthService, private router: Router) 
  


  /**
   * intercept all XHR request
   * @param request
   * @param next
   * @returns Observable
   */
  intercept(request: HttpRequest, next: HttpHandler): Observable> 

    if (localStorage.getItem('jwtToken')) 
      request = request.clone(
        setHeaders: 
          Authorization: 'Bearer ' + localStorage.getItem('jwtToken')
        
      );
    

    /**
     * continues request execution
     */
    return next.handle(request).pipe(catchError((error, caught) => 
        //intercept the respons error and displace it to the console
        console.log(error);
        this.handleAuthError(error);
        return of(error);
      ) as any);
  


  /**
   * manage errors
   * @param err
   * @returns any
   */
  private handleAuthError(err: HttpErrorResponse): Observable 
    //handle your auth error or rethrow
    if (err.status === 401) 
      //navigate /delete cookies or whatever
      console.log('handled error ' + err.status);
      this.router.navigate([`/login`]);
      // if you've caught / handled the error, you don't want to rethrow it unless you also want downstream consumers to have to handle it as well.
      return of(err.message);
    
    throw err;
  

No olvide registrar su interceptor en app.module.ts al igual que:

import  TokenInterceptor  from './auth/token.interceptor';

@NgModule(
  declarations: [],
  imports: [],
  exports: [],
  providers: [
    
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true,
    
  ],
  bootstrap: [AppComponent]
)
export class AppModule  

De la respuesta de @ firegloves, para tener el .pipe los manipuladores de servicios individuales realmente pueden catchError sus propios códigos de falla HTTP, deberá estructurar el código de tal manera que:

  1. Si el Interceptor detecta un código de error HTTP 401, manipúlelo y devuélvalo of(error) que potencialmente se puede manejar normalmente en cualquier subsiguiente .pipe‘s.
  2. Si el código de error HTTP es uno para el que Interceptor no está diseñado, throw nuevamente para que los controladores de errores posteriores, como los de sus servicios, puedan detectar y manejar errores que no sean 401 para sus propias llamadas.

Mi interceptor tiene un doble trabajo. Eso:

  1. Inyecta un Authorization encabezado en todas las solicitudes salientes, si tiene un token almacenado.
  2. Intercepta errores HTTP 401 no autenticados, momento en el que invalida el almacén de tokens y luego vuelve a redireccionar a /login.
import  Injectable  from '@angular/core';
import  Router  from '@angular/router';
import 
    HttpErrorResponse,
    HttpEvent,
    HttpHandler,
    HttpInterceptor,
    HttpRequest,
 from '@angular/common/http';
import  Observable  from 'rxjs';
import  catchError  from 'rxjs/operators';
import  of  from 'rxjs/observable/of';

import  AuthService  from './auth.service';

@Injectable(
    providedIn: 'root',
)
export class RequestInterceptor implements HttpInterceptor 

    constructor(
        private readonly auth: AuthService,
        private readonly router: Router,
    ) 
    

    /**
     * @param HttpRequest request - The intercepted request
     * @param HttpHandler next - The next interceptor in the pipeline
     * @return Observable>
     */
    intercept(request: HttpRequest, next: HttpHandler): Observable> 
        request = this.addToken(request);
        return next.handle(request)
            // add error handling
            .pipe(
                catchError(
                    (error: any, caught: Observable>) => 
                        if (error.status === 401) 
                            this.handleAuthError();
                            // if you've caught / handled the error, you don't
                            // want to rethrow it unless you also want
                            // downstream consumers to have to handle it as
                            // well.
                            return of(error);
                        
                        throw error;
                    
                ),
            );
    

    /**
     * Handle API authentication errors.
     */
    private handleAuthError() 
        // clear stored credentials; they're invalid
        this.auth.credentials = null;
        // navigate back to the login page
        this.router.navigate(['/login']);
    

    /**
     * Add stored auth token to request headers.
     * @param HttpRequest request - the intercepted request
     * @return HttpRequest - the modified request
     */
    private addToken(request: HttpRequest): HttpRequest 
        const token: string = this.auth.token;
        if (token) 
            return request.clone(
                setHeaders: 
                    Authorization: `Bearer $token`,
                ,
            );
        
        return request;
    


Todos AuthService lo que hace es tener un get / set público que inserta un objeto de credenciales en localStorage – se asegura de que el token no esté caducado, pero puedes diseñarlo como quieras.

Como @firegloves se indicó anteriormente, debe agregar el Interceptor a la tubería en app.module.ts:

import  RequestInterceptor  from './auth/request.interceptor';

@NgModule(
    declarations: [],
    imports: [],
    exports: [],
    providers: [
        
            provide: HTTP_INTERCEPTORS,
            useClass: RequestInterceptor,
            multi: true,
        ,
    ],
    bootstrap: [AppComponent],
)
export class AppModule  

valoraciones y reseñas

Si tienes alguna desconfianza y disposición de reformar nuestro división puedes dejar un comentario y con gusto lo interpretaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *