Guida alla gestione delle eccezioni in Express PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Guida alla gestione delle eccezioni in Express

Introduzione

Eccezioni ed errori sono destinati a verificarsi mentre gli utenti interagiscono con qualsiasi applicazione, spetta agli ingegneri del software scegliere un mezzo per gestire qualsiasi errore che potrebbe sorgere, consapevolmente o inconsapevolmente. Di conseguenza, gli sviluppatori back-end che creano API con Express si ritrovano a lavorare per assicurarsi di creare un'API utile, efficiente e utilizzabile. Ciò che è più importante è gestire gli errori in modo tale da costruire un sistema robusto perché questo aiuta a ridurre i tempi di sviluppo, gli errori veri e propri, i problemi di produttività e determina il successo o la scalabilità dello sviluppo del software.

È necessario registrare il messaggio di errore, sopprimere l'errore, informare gli utenti dell'errore o scrivere codice per gestire gli errori? Non chiederti più.

In questa guida, impareremo come creare una solida base di codice per la gestione degli errori per le applicazioni Express, che servirà per aiutare a rilevare gli errori dell'applicazione e intraprendere azioni ottimali per ripristinare qualsiasi applicazione da un errore normale durante il runtime.

Nota: Utilizzeremo Postman per testare l'API nella nostra demo. Puoi scaricarlo sul Pagina di download del postino. In alternativa, puoi semplicemente utilizzare il browser, la riga di comando curl strumento o qualsiasi altro strumento con cui potresti avere familiarità.

Cos'è la gestione degli errori?

Nello sviluppo del software, ci sono due diversi tipi di eccezioni: operativa ed programmatica.

  • Potrebbero verificarsi errori operativi durante il runtime e, per evitare che l'applicazione si interrompa bruscamente, dobbiamo gestire con garbo queste eccezioni attraverso metodi di gestione degli errori efficienti.
  • Le eccezioni programmatiche vengono lanciate manualmente da un programmatore, quando si verifica uno stato eccezionale.

Puoi pensare alle eccezioni operative come eccezioni "impreviste, ma previste" (come l'accesso a un indice fuori dai limiti) e alle eccezioni programmatiche come eccezioni "previste e previste" (come un'eccezione di formattazione dei numeri).

La gestione delle eccezioni è la procedura utilizzata per trovare e correggere i difetti all'interno di un programma. La gestione degli errori invia messaggi che includono il tipo di errore verificatosi e lo stack in cui si è verificato l'errore.

Nota: In informatica, le eccezioni sono recuperabili e in genere derivano da problemi operativi o programmatici durante il runtime. Gli errori in genere derivano da fattori esterni, come limitazioni hardware, problemi di connettività, mancanza di memoria, ecc. In JavaScript, i termini sono spesso usati in modo intercambiabile e le eccezioni personalizzate derivano dal Error classe. Il Error class stessa rappresenta sia gli errori che le eccezioni.

In Express, la gestione delle eccezioni si riferisce al modo in cui Express si configura per rilevare ed elaborare le eccezioni sincrone e asincrone. L'aspetto positivo della gestione delle eccezioni in Express è che come sviluppatore non è necessario scrivere i propri gestori di eccezioni; Express viene fornito con un gestore di eccezioni predefinito. Il gestore delle eccezioni aiuta a identificare gli errori e a segnalarli all'utente. Fornisce inoltre varie strategie correttive e le implementa per mitigare le eccezioni.

Sebbene queste possano sembrare molte cose nascoste, la gestione delle eccezioni in Express non rallenta il processo complessivo di un programma né ne sospende l'esecuzione.

Comprensione della gestione delle eccezioni in Express

Con il gestore degli errori predefinito fornito con Express, abbiamo in mano una serie di funzioni middleware che aiutano a rilevare automaticamente gli errori nei gestori di route. Presto creeremo un progetto per mettere in pratica la teoria su come restituire errori corretti in un'app Express e su come non far trapelare informazioni sensibili.

Definizione della funzione middleware in Express

Le funzioni middleware di gestione degli errori sono definite in modo tale da accettare un Error object come primo parametro di input, seguito dai parametri predefiniti di qualsiasi altra funzione middleware: request, responsee next. next() La funzione salta tutto il middleware corrente al gestore degli errori successivo per il router.

Impostazione della gestione degli errori in Express

Esegui il seguente comando nel tuo terminale per creare un'app Node and Express:

$ mkdir error-handling-express

Nella cartella appena creata, inizializziamo un nuovo progetto Node:

$ cd error-handling-express && npm init -y

Questo crea a package.json file nella nostra cartella.

Per creare un server Express nella nostra app Node, dobbiamo installare il file express pacchetto, dotenv per caricare automaticamente le variabili di ambiente in .env file in process.env oggetto, e nodemon per riavviare l'app del nodo se viene annotata una modifica del file nella directory.

$ npm install express dotenv nodemon

Quindi, crea un app.js file nella cartella del progetto che fungerà da file di indice per l'app.

Ora che abbiamo installato tutte le dipendenze necessarie per la nostra app Express, dobbiamo impostare lo script per leggere l'app nel package.json file. Per raggiungere questo obiettivo, il package.json file, in modo che il scripts oggetto è come mostrato di seguito:

"scripts": {
    "start": "nodemon app.js"
},

In alternativa, puoi saltare l'uso nodemone utilizzare node app.js anziché.

Configurazione di un server Express

Per configurare il server, dobbiamo prima importare i vari pacchetti in app.js. Creeremo anche un .env file nella directory del progetto - per memorizzare tutte le variabili di ambiente per l'applicazione:



const express = require('express')
require('dotenv').config

PORT=4000 

Abbiamo definito il numero di porta per l'app in .env, che viene caricato e letto da dotenv, ed è possibile accedervi successivamente.

Inizializzazione dell'Express Server

Ora, dobbiamo inizializzare il server Express e fare in modo che la nostra app ascolti il ​​numero di porta dell'app, insieme a una richiesta a un percorso di prova: /test. Aggiorniamo app.js, sotto le dichiarazioni di importazione:


const app = express();
const port = process.env.PORT || 4000;

app.get("/test", async (req, res) => {
    return res.status(200).json({ success: true });
});

app.listen(port, () => {
    console.log(`Server is running at port ${port}`);
});

Da qui in poi impareremo come gestire i vari casi d'uso di errori operativi che si possono incontrare in Express.

Gestione degli errori non trovati in Express

Supponiamo di dover recuperare tutti gli utenti da un database di utenti, è possibile gestire in modo efficiente un potenziale scenario di errore in cui non esistono dati nel database, avvolgendo la logica in un try/catch block - sperando di rilevare qualsiasi errore che potrebbe proiettare nel file catch bloccare:


const getUser = () => undefined;

app.get("/get-user", async (req, res) => {
	try {
		const user = getUser();
		if (!user) {
			throw new Error('User not found');
		}
	} catch (error) {
	    
		console.log(error); 
		
		res.status(400).send(error.message) 
	}
	return res.status(200).json({
		success: true
	});
});

Questo risulta in:

User not found

Ora, quando viene effettuata questa richiesta (puoi testare usando Postman) e nessun utente esiste nel database, il client riceve un messaggio di errore che dice "Utente non trovato". Inoltre, noterai che l'errore viene registrato anche nella console.

Ottimizzazione della gestione degli errori con il middleware del gestore degli errori

Possiamo ottimizzare lo sviluppo creando un middleware di gestione degli errori che verrebbe alla fine di tutti i percorsi definiti, in modo che se viene generato un errore in uno dei percorsi, Express darà automaticamente un'occhiata al middleware successivo e continuerà a scorrere l'elenco finché non raggiunge il gestore degli errori. Il gestore degli errori elaborerà l'errore e invierà anche una risposta al client.

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

Per iniziare, crea una cartella chiamata middleware nella directory del progetto, e in questa cartella, crea un file chiamato errorHandler.js che definisce il gestore degli errori:

const errorHandler = (error, req, res, next) => {
    
    console.log(error); 
    
    res.status(400).send(error.message); 
}
module.exports = errorHandler;

Nella nostra funzione middleware, abbiamo reso Express consapevole che questa non è una funzione middleware di base, ma un gestore di errori, aggiungendo il error parametro prima dei 3 parametri di base.

Ora useremo il gestore degli errori nella nostra demo app.js e gestire l'errore iniziale di recupero degli utenti con il middleware del gestore degli errori, come mostrato di seguito:


const getUser = () => undefined;

app.get("/get-user", async (req, res, next) => {
	try {
		const user = getUser();
		if (!user) {
			throw new Error("User not found");
		}
	} catch (error) {
		return next(error);
	}
});

app.use(errorHandler);

Possiamo ottimizzare ancora di più il nostro codice, creando un abtsraction attorno al try/catch logica. Possiamo ottenere ciò creando una nuova cartella nella directory del progetto chiamata utils, e in esso, crea un file chiamato tryCatch.js.

Per astrarre il try-catch logica: possiamo definire una funzione che accetta un'altra funzione (nota come controllore) come parametro e restituisce an async funzione che manterrà a try/catch per qualsiasi controller ricevuto.

Se si verifica un errore nel controller, viene rilevato nel file catch block e viene chiamata la funzione successiva:


const tryCatch = (controller) => async (req, res, next) => {
	try {
		await controller(req, res);
	} catch (error) {
		return next(error);
	}
};
module.exports = tryCatch;

Grazie alla try/catch astrazione, possiamo eseguire il refactoring del nostro codice per renderlo più succinto saltando il file try-catch clausola in modo esplicito durante il recupero degli utenti in app.js:


const getUser = () => undefined;

app.get(
	"/get-user",
	tryCatch(async (req, res) => {
		const user = getUser();
		if (!user) {
			throw new Error("User not found");
		}
		res.status(400).send(error.message);
	})
);

Abbiamo estratto con successo la logica try-catch e il nostro codice funziona ancora come prima.

Gestione degli errori di convalida in Express

Per questa demo, creeremo un nuovo percorso nella nostra app Express per l'accesso, per convalidare un ID utente al momento dell'accesso. Innanzitutto, installeremo il joi pacchetto, per aiutare con la creazione di uno schema, con il quale possiamo applicare i requisiti:

$ npm i joi

Quindi, crea uno schema che è a Joi.object con una userId che deve essere un numero ed è obbligatorio, il che significa che la richiesta deve corrispondere a un oggetto con un ID utente su di esso.

Possiamo usare il validate() metodo nell'oggetto schema per convalidare ogni input rispetto allo schema:


const schema = Joi.object({
	userId: Joi.number().required(),
});

app.post(
	"/login",
	tryCatch(async (req, res) => {
		const {error, value} = schema.validate({});
		if (error) throw error;
	})
);

Se un oggetto vuoto viene passato nel file validate() metodo, l'errore verrebbe gestito con garbo e il messaggio di errore verrebbe inviato al client:

Sulla console, abbiamo anche accesso a a details array che include vari dettagli sull'errore che potrebbero essere comunicati all'utente se necessario.

Per gestire in modo specifico gli errori di convalida in modo tale da passare il dettaglio dell'errore appropriato per errore di convalida, è possibile eseguire il refactoring del middleware del gestore degli errori:


const errorHandler = (error, req, res, next) => {
	console.log(error); 

	if (error.name === "ValidationError") {
		return res.status(400).send({
			type: "ValidationError",
			details: error.details,
		});
	}

	res.status(400).send(error.message); 
};

module.exports = errorHandler;

Con errorHandler.js ora personalizzato, quando facciamo la stessa richiesta con un oggetto vuoto passato al validate() Metodo:

Guida alla gestione delle eccezioni in Express PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Ora abbiamo accesso a un oggetto personalizzato che restituisce i messaggi in modo più leggibile/amichevole. In questo modo siamo in grado di inviare e gestire diversi tipi di errore in base al tipo di errore in arrivo.

Conclusione

In questa guida, abbiamo esaminato ogni aspetto della gestione degli errori di Express.js, incluso il modo in cui il codice sincrono e asincrono viene gestito per impostazione predefinita, come creare le proprie classi di errore, come scrivere funzioni middleware personalizzate per la gestione degli errori e fornire next come responsabile finale delle catture

Come per ogni attività là fuori, ci sono anche best practice durante lo sviluppo che includono un'efficace gestione degli errori, e oggi abbiamo imparato come possiamo gestire gli errori in un'app Express in modo affidabile.

Gestire correttamente gli errori non significa solo ridurre i tempi di sviluppo trovando facilmente bug ed errori, ma anche sviluppare una solida base di codice per applicazioni su larga scala. In questa guida abbiamo visto come configurare il middleware per la gestione degli errori operativi. Alcuni altri modi per migliorare la gestione degli errori includono: non inviare tracce dello stack, arrestare i processi con garbo per gestire le eccezioni non rilevate, fornire messaggi di errore appropriati, inviare registri degli errori e impostare una classe che estenda il Error classe.

Spero che gli esempi che ho usato in questo tutorial siano stati piacevoli per te. Ho coperto vari scenari che potresti potenzialmente incontrare durante la scrittura di un'applicazione Express da utilizzare nel mondo reale sulla gestione degli errori. Per favore, fammi sapere se c'è qualcosa che mi sono perso. Ci avvantaggerà e aiuterà anche me a saperne di più. Buona giornata e grazie per aver letto.

Puoi fare riferimento a tutto il codice sorgente utilizzato nell'articolo su Github.

Risorse addizionali

Timestamp:

Di più da Impilamento