En este tutorial, se le presentarán los errores HTTP en JavaScript, y cómo usar el HttpClient con operadores de manejo de errores RxJS y, finalmente, cómo usar el HttpInterceptor

Esta es una inmersión profunda en el manejo de errores HTTP en Angular 7, es posible que desee consultar la publicación introductoria sobre el manejo de errores aquí.

Requisitos previos

Para poder seguir la demostración de este tutorial, debe tener:

  • Node versión 11.0 instalado en su máquina.
  • Gestor de paquetes de nodos versión 6.7 (normalmente viene con instalación de nodos).
  • Angular CLI versión 7.0
  • La última versión de Angular (versión 7)
 // run the command in a terminal ng version

Confirme que está utilizando la versión 7 y actualice a 7 si no lo está.Otras cosas que serán agradables de tener son:

  • Un conocimiento práctico del marco Angular a nivel principiante.
  • La familiaridad con los servicios de Angular será una ventaja, pero no un requisito.

Errores externos

Estos son errores que llamamos errores del lado del servidor porque provienen principalmente del exterior de la aplicación Angular y siempre se devuelve un HttpErrorResponse en cualquier momento que ocurran. Tiene propiedades como:

  • Nombre de error: indica el nombre del error.
  • Mensaje de error: intenta explicar el error en términos simples para facilitar la comprensión.
  • estado de Error: cada tipo de error del lado del servidor tiene un código asignado para diferenciarlo del resto. Estos códigos suelen ser códigos de tres dígitos, como 400, que significa que la solicitud enviada fue inesperada, o 500, que indica un error interno del servidor, etc.

Controlador de errores en Angular

Angular tiene una clase de manejo de errores global llamada Controlador de errores que proporciona un gancho para el manejo centralizado de excepciones dentro de la aplicación. Básicamente, intercepta todos los errores que ocurren en su aplicación, los registra todos en la consola y evita que la aplicación se bloquee.La sintaxis se ve así:

 class MyErrorHandler implements ErrorHandler { handleError(error) { // do something with the exception } } @NgModule({ providers: }) class MyModule {}

Esta es una gran manera de manejar errores en Angular, particularmente los errores internos.

La limitación de ErrorHandler

Si ha seguido el post introductorio aquí, verá cómo la clase Angular ErrorHandler fue la solución definitiva para centralizar el concepto de error try/catch en nuestra aplicación. Sin embargo, cuando queremos centrarnos en los errores del lado del servidor, descubrimos que la clase ErrorHandler no puede funcionar directamente con solicitudes HTTP en nuestra aplicación. Good news is Angular proporciona una especie de interfaz donde puede usar el concepto de la clase ErrorHandler para tratar directamente con las solicitudes HTTP.

Solución 1: Angular HttpClient

El (https://angular.io/api/common/http/HttpClient) in @angular/common/``(https://angular.io/api/common/http)ofrece una API HTTP de cliente simplificada para aplicaciones Angulares que se basa en la interfaz XMLHttpRequest expuesta por los navegadores. Los beneficios adicionales de (https://angular.io/api/common/http/HttpClient) incluyen características de capacidad de prueba, objetos de solicitud y respuesta escritos, interceptación de solicitudes y respuestas, API Observable y manejo de errores simplificado. Por lo tanto, al usar este cliente con algunos operadores RxJS, podemos obtener una forma de intentar/atrapar el manejo de errores, pero esta vez se comunica directamente con las solicitudes HTTP a través de una aplicación Angular en un servicio. Lo entenderás mejor en acción.

Demo

Esta es una aplicación jsonplaceholder de demostración donde se muestran partes de los datos disponibles en el jsonplaceholder en la interfaz de usuario, un servicio perfecto para demostrar conceptos relacionados con el servidor. Si tienes listos todos los requisitos previos indicados al principio de la publicación, puedes descargar el proyecto desde GitHub aquí. Descomprima y abra el proyecto en Código VS y use el terminal para inicializar los módulos de nodo:

 npm install

Ahora que su aplicación está en funcionamiento, primero debe asegurarse de que el módulo necesario para que las aplicaciones de Angular utilicen cualquier servicio de servidor esté activo en su aplicación. Navegue a su archivo app.module.ts y confirme que hay una instrucción de importación como esta:

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

Su aplicación tiene cuatro componentes: publicaciones, barra lateral, detalles y usuarios. También tiene un servicio llamado data service donde se realizan todas las solicitudes HTTP. Su archivo data.service.ts debería tener este aspecto:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/users') } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } }

Se están realizando tres solicitudes al servidor, ahora si elige una de estas solicitudes, diga getUsers() y desea agregar manejo de errores con HttpClient, entonces:

  • Importe el objeto catchError de los operadores RxJS.
  • Importar throwError desde RxJS.
  • Utilice el método pipe para introducirlo en la solicitud HTTP deseada.
  • Crear un método para manejar el error

Si sigue estos, su archivo data.service.ts se verá así:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { catchError } from 'rxjs/operators' import { throwError } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usssers') .pipe( catchError(this.handleError) ); } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } }

Verá que la solicitud get se manipuló deliberadamente para garantizar que se produjera un error. Cuando ejecute la aplicación, verá el error registrado con el mensaje de registro que queremos.

A veces, cuando envía una solicitud a un servidor lento bien conocido, sabe que puede tomar un tiempo obtener respuesta o realizar algunos intentos para obtener respuesta del servidor, puede reenviar la solicitud varias veces antes de lanzar el error. Esto se puede lograr con el método de reintento en RxJS, por lo que importa el operador de reintento y luego puede usarlo dentro de la tubería como se usa a continuación:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { catchError, retry } from 'rxjs/operators' import { throwError } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usssers') .pipe( retry(2), catchError(this.handleError) ); } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } }

Si ejecuta la aplicación, la consola debería tener este aspecto:

lo vuelve a intentar dos veces tal como lo especificamos antes de lanzar el mensaje de registro de errores.

También es muy importante que su reintento se encuentre antes del error de captura para que el mensaje de error no se registre después de cada prueba.

Esta solución funciona perfectamente siempre que su aplicación tenga un servicio y probablemente una solicitud get, pero cuando su aplicación es grande y tiene muchos servicios o muchas más solicitudes por servicio, se convierte en una solución ineficiente. Esto se debe a que siempre debe copiar la función de error de controlador en todos los servicios y repetir el código incluso dentro de un servicio. Imagine el costo de memoria de depurar y mantener la base de código.

La mejor opción: Angular HttpInterceptor

Al igual que su nombre lo indica, Angular proporciona una interfaz llamada HttpInterceptor que puede interceptar (https://angular.io/api/common/http/HttpRequest) y (https://angular.io/api/common/http/HttpResponse) y crea una plataforma para manejarlos. Esto significa que tenemos acceso directo a las solicitudes de nuestro servidor, ¡qué mejor lugar para lidiar con los errores del servidor que aquí!La sintaxis es la siguiente:

 interface HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> }

Para usar HttpInterceptor , cree un nuevo servicio en el que desee que su lógica interceptora vaya con la CLI Angular:

 ng generate service services/interceptor

Ahora que ha generado un servicio interceptor, navegue a su archivo app.module.ts para registrarlo en consecuencia, de la siguiente manera:

 // src/app/app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { UsersComponent } from './components/users/users.component'; import { DetailsComponent } from './components/details/details.component'; import { PostsComponent } from './components/posts/posts.component'; import { SidebarComponent } from './components/sidebar/sidebar.component'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { InterceptorService } from './services/interceptor.service'; @NgModule({ declarations: , imports: , providers: , bootstrap: }) export class AppModule { }

El siguiente paso es deshacerse de toda la lógica de manejo de errores en el data.service.ts archivo, el archivo debería tener este aspecto cuando haya terminado:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usersss') } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } }

Copie el código a continuación en el interceptor.service.ts archivo:

 // src/app/services/interceptor.service.ts import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class InterceptorService implements HttpInterceptor{ constructor() { } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{ return next.handle(req) .pipe( catchError(this.handleError) ) }; }

Si ejecuta la aplicación, puede ver que registra nuestro mensaje de error y lanza el error tal como lo esperamos. Este es el mejor método para manejar errores de servidor en su proyecto Angular. Puede probar las tres solicitudes a la vez para detectar errores manipulándolas. Cuando lo haga, descubrirá que el interceptor los atrapa a todos y registra nuestro mensaje para cada uno, es realmente increíble de ver.

Conclusión

Se le han presentado varias formas de manejar los errores del lado del servidor en sus aplicaciones de Angular. También ha visto cuándo usar y cuándo no usar el HttpClient con los operadores RxJS y cómo la mejor manera es usar interceptores. En el siguiente tutorial de esta serie, se le presentará el seguimiento de errores. El código completo de este tutorial está en GitHub y se puede encontrar aquí. ¡Feliz programación!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.