Graziosa gestione degli errori RxJS |  HTMLGoodies.com
Tempo di lettura: 3 minuti

Le applicazioni della mia organizzazione fanno ampio uso della libreria RxJS per sottoscrivere API che trasferiscono dati da e verso database e fornitori di informazioni. Se hai trascorso un po’ di tempo su Internet, sei senza dubbio fin troppo consapevole che effettuare chiamate attraverso il filo è soggetto a ogni sorta di singhiozzo. Questi possono derivare da congestione della rete, guasti hardware o bug delle applicazioni. Per questi motivi, devi gestire con cura i tuoi abbonamenti RxJS. Parte di questo include assicurarsi di chiudere gli abbonamenti attivi una volta che non sono più necessari. L’altro modo per proteggersi dagli imprevisti consiste nell’utilizzare una rigorosa gestione degli errori. A causa della loro natura asincrona, il blocco try/catch standard non lo taglierà. Invece, RxJS fornisce alcuni dei propri meccanismi per gestire con grazia gli inevitabili errori che derivano dalle chiamate di rete. Questo articolo si concentrerà su due di questi: Iscriviti Richiamate e il catchError operatore.

La richiamata dell’errore di iscrizione

Oltre a un osservatore o una funzione, il sottoscrivi() accetta anche due parametri Function aggiuntivi: uno per la gestione degli errori e un altro che viene eseguito al completamento con successo. Puoi vederli qui in VS Code:

Di seguito è riportato un esempio di chiamata API che recupera le impostazioni utente da un archivio dati. Se si verifica un errore, il viewType è impostato sul valore predefinito e l’errore viene rigettato:

this.userService.getSettings(userid)
.subscribe(userSettings => {
this.viewType = userSettings.settings['viewType'] || this.viewSelectionValues.circle;
},
error => {
this.viewType = this.viewSelectionValues.circle;
if (error.status && error.status !== 404) {
throw error;
}
});

In questo caso, il gestore degli errori sta effettivamente svolgendo un doppio compito: oltre a impostare il tipo di visualizzazione predefinito, filtra anche gli errori 404, il che significa che non sono state trovate impostazioni per quell’utente. Questo non è un vero errore perché è previsto per i nuovi utenti.

L’operatore catchError

La richiamata dell’errore di sottoscrizione dovrebbe essere la prima scelta per la gestione degli errori di sottoscrizione RxJS. Tuttavia, questo approccio presenta alcune limitazioni. Ad esempio, non è possibile recuperare dall’errore o emettere un valore di fallback che sostituisca quello che ci aspettavamo dall’API. Per questo, c’è il catchError operatore. Come la maggior parte degli operatori RxJS, catchError è in realtà una funzione che accetta un input osservabile ed emette un output osservabile. In caso di errore, catchError passa l’errore alla funzione di gestione degli errori. Ci si aspetta quindi che tale funzione restituisca un Observable che sarà un Observable sostitutivo per il flusso che ha appena generato un errore.

In questa versione rifattorizzata del nostro primo esempio, il catchError operatore è impiegato per intercettare gli errori prima della sottoscrizione. Nel catchError funzione handler, l’errore viene scartato e viene fornito un valore predefinito. Pertanto, il gestore degli errori non viene mai richiamato:

this.userService.getSettings(userid)
.pipe(
catchError( err => of({settings: this.viewSelectionValues.circle}) )
)
.subscribe(userSettings => {
this.viewType = userSettings.settings['viewType'] || this.viewSelectionValues.circle;
},
error => console.log('HTTP Error', error));

Rilanciare l’errore

Sebbene catchError ha la capacità di sostituire l’osservabile corrente con uno nuovo, puoi comunque generare un errore se lo desideri. Per fare ciò, restituire i risultati di lancioErrore() funzione. Puoi passare l’errore originale o uno nuovo personalizzato:

this.userService.getSettings(userid)
.pipe(
catchError(err => {
if (error.status && error.status !== 404) {
console.log('Error encountered while fetching user settings!', err);
return throwError(err);
}
else {
return of({settings: this.viewSelectionValues.circle});
}
}
)
.subscribe(userSettings => {
this.viewType = userSettings.settings['viewType'] || this.viewSelectionValues.circle;
};

Riprovare dopo un errore

Anche se non possiamo recuperare dopo un errore di flusso, non c’è nulla che ci impedisca di abbonarci nuovamente alla fonte osservabile del flusso (cioè il servizio). Il segreto per riprovare è il riprovaQuando operatore. Ritenta automaticamente un osservabile in caso di errore:

let retryAttempts = 0;
this.userService.getSettings(this.userid)
.pipe(
retryWhen(errors =>
errors.pipe(
delayWhen(() => {
console.log(`Retry attempt #${++retryAttempts}`);
return timer(2000);
}),
take(3)
)
)
)
.subscribe(userSettings => {
this.viewType = userSettings.settings['viewType'] || this.viewSelectionValues.circle;
};

riprovaQuando Extra!

Una cosa importante da tenere a mente sul riprova quando Operatore, è che la funzione che definisce l’osservabile di notifica viene chiamata solo una volta. Se vuoi provare un paio di volte, puoi includere il prendere() operatore. È ancora più potente quando lo abbini a ritardoQuando(). Quest’ultima causa riprovaQuando per riprovare dopo la durata specificata tramite il Timer() operatore.

Nota che dovrai importare oggetti e operatori RxJS per usarli:

import { Observable, timer } from "https://cdn.skypack.dev/rxjs";
import { retryWhen, tap, delayWhen, take } from "https://cdn.skypack.dev/rxjs/operators";

Ecco la demo su Codepen.io. Mostra come utilizzare i callback di errore di sottoscrizione e il riprovaQuando operatore:

Ti consigliamo di aprire la console integrata per visualizzare l’output di registrazione.

Conclusione

La corretta gestione degli errori è fondamentale per lavorare con servizi asincroni su una rete a causa dell’enorme numero di problemi che possono sorgere. Tra i callback di sottoscrizione della libreria RxJS e il catchError operatore, puoi scegliere di gestire con garbo un errore o lasciarlo scorrere per avvisare l’utente.

Source link

Di Simone Serra

Web Designer Freelancer Realizzazione Siti Web Serra Simone Realizzo siti web, portali ed e-commerce con focus specifici sull’usabilità, l’impatto grafico, una facile gestione e soprattutto in grado di produrre conversioni visitatore-cliente. Elaboro siti internet, seguendo gli standard Web garantendo la massima compatibilità con tutti i devices. Sviluppo e-commerce personalizzati, multilingua, geolocalizzati per potervi mettere nelle migliori condizioni di vendita. Posiziono il tuo sito su Google per dare maggiore visibilità alla tua attività sui motori di ricerca con SEO di base o avanzato.