Guide till undantagshantering i Express PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Guide till undantagshantering i Express

Beskrivning

Undantag och fel kommer oundvikligen att inträffa när användare interagerar med vilken applikation som helst, det är upp till mjukvaruingenjörer att välja ett sätt att hantera alla fel som kan uppstå – medvetet eller omedvetet. Som ett resultat finner backend-utvecklare som bygger API:er med Express att de arbetar för att säkerställa att de bygger ett användbart, effektivt och användbart API. Det som är av största vikt är att hantera fel på ett sådant sätt att man bygger ett robust system eftersom detta hjälper till att minska utvecklingstiden, direkta fel, produktivitetsproblem och avgör framgången eller skalbarheten för mjukvaruutveckling.

Behöver du logga felmeddelandet, undertrycka felet, meddela användare om felet eller skriva kod för att hantera fel? Undrar inte mer.

I den här guiden kommer vi att lära oss hur man bygger en robust kodbas för felhantering för Express-applikationer, som hjälper till att upptäcka applikationsfel och vidta optimala åtgärder för att återställa alla applikationer från att misslyckas under körning.

Notera: Vi kommer att använda Postman för att testa API:et i vår demo. Du kan ladda ner den på Postman nedladdningssida. Alternativt kan du helt enkelt använda webbläsaren, kommandoraden curl verktyg eller något annat verktyg som du kanske känner till.

Vad är felhantering?

Inom mjukvaruutveckling finns det två olika typer av undantag: operativa och programma.

  • Driftsfel kan uppstå under körning, och för att förhindra att applikationen avslutas abrupt måste vi på ett elegant sätt hantera dessa undantag genom effektiva felhanteringsmetoder.
  • Programatiska undantag kastas manuellt av en programmerare när ett exceptionellt tillstånd uppstår.

Du kan tänka på operationella undantag som "oväntade, men förutsedda" undantag (som att komma åt ett index utanför gränserna) och programmatiska undantag som "förväntade och förutsedda" undantag (som ett nummerformateringsundantag).

Undantagshantering är den procedur som används för att hitta och åtgärda brister i ett program. Felhantering skickar meddelanden som inkluderar typen av fel som inträffade och stacken där felet inträffade.

Notera: Inom datavetenskap kan undantag återställas från och härrör vanligtvis från antingen operativa eller programmatiska problem under körning. Fel uppstår vanligtvis från externa faktorer, såsom hårdvarubegränsningar, problem med anslutning, brist på minne, etc. I JavaScript används termerna ofta omväxlande och anpassade undantag härleds från Error klass. De Error klass i sig representerar både fel och undantag.

I Express avser undantagshantering hur Express ställer in sig för att fånga och bearbeta synkrona och asynkrona undantag. Det som är bra med undantagshantering i Express är att du som utvecklare inte behöver skriva dina egna undantagshanterare; Express kommer med en standard undantagshanterare. Undantagshanteraren hjälper till att identifiera fel och rapportera dem till användaren. Den tillhandahåller också olika korrigerande strategier och implementerar dem för att mildra undantag.

Även om dessa kan verka som en massa saker som går under huven, saktar inte undantagshanteringen i Express ner den övergripande processen för ett program eller pausar dess körning.

Förstå undantagshantering i Express

Med standardfelhanteraren som följer med Express har vi i våra händer en uppsättning middleware-funktioner som hjälper till att fånga upp fel i rutthanterare automatiskt. Snart kommer vi att skapa ett projekt för att omsätta teori i praktiken om hur man returnerar korrekta fel i en Express-app och hur man inte läcker känslig information.

Definiera middleware-funktion i Express

Mellanvarufunktionerna för felhantering är definierade på ett sådant sätt att de accepterar en Error objekt som den första indataparametern, följt av standardparametrarna för alla andra mellanprogramfunktioner: request, responseoch next. De next() funktionen hoppar över all aktuell mellanprogramvara till nästa felhanterare för routern.

Konfigurera felhantering i Express

Kör följande kommando i din terminal för att skapa en Node and Express-app:

$ mkdir error-handling-express

I den nyskapade mappen, låt oss initiera ett nytt nodprojekt:

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

Detta skapar en package.json fil i vår mapp.

För att skapa en Express-server i vår Node-app måste vi installera express paket, dotenv för automatisk inläsning av miljövariabler .env fil till process.env objekt, och nodemon för att starta om nodappen om en filändring noteras i katalogen.

$ npm install express dotenv nodemon

Skapa sedan en app.js fil i projektmappen som kommer att fungera som indexfil för appen.

Nu när vi har installerat alla nödvändiga beroenden för vår Express-app måste vi ställa in skriptet för att läsa appen i package.json fil. För att uppnå det måste package.json fil, så att scripts objektet är som visas nedan:

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

Alternativt kan du hoppa över att använda nodemonoch användning node app.js istället.

Konfigurera en Express-server

För att ställa in servern måste vi först importera de olika paketen till app.js. Vi kommer också att skapa en .env fil i projektkatalogen – för att lagra alla miljövariabler för applikationen:



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

PORT=4000 

Vi har definierat portnumret för appen i .env, som laddas in och läses av dotenv, och kan nås senare.

Initiering av Express-servern

Nu måste vi initiera Express-servern och få vår app att lyssna på appens portnummer, tillsammans med en begäran om en testrutt – /test. Låt oss uppdatera app.js, under importförklaringarna:


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}`);
});

Härifrån kommer vi att lära oss hur man hanterar olika användningsfall av operativa fel som kan uppstå, i Express.

Hantering av ej hittade fel i Express

Anta att du behöver hämta alla användare från en databas med användare, kan du effektivt hantera ett potentiellt felscenario där inga data finns i databasen, genom att linda in logiken i en try/catch blockera – i hopp om att fånga eventuella fel som kan projicera i catch blockera:


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
	});
});

Detta resulterar i:

User not found

Nu, när denna begäran görs (du kan testa med Postman) och ingen användare finns i databasen, får klienten ett felmeddelande som säger "Användaren hittades inte". Du kommer också att märka att felet loggas i konsolen också.

Optimera felhantering med Error Handler Middleware

Vi kan optimera utvecklingen genom att skapa en mellanprogram för felhanterare som skulle komma i slutet av alla definierade rutter, så att om ett fel kastas i en av rutterna, kommer Express automatiskt att titta på nästa mellanprogram och fortsätta att gå ner i listan tills den når felhanteraren. Felhanteraren kommer att bearbeta felet och även skicka tillbaka ett svar till klienten.

Kolla in vår praktiska, praktiska guide för att lära dig Git, med bästa praxis, branschaccepterade standarder och medföljande fuskblad. Sluta googla Git-kommandon och faktiskt lära Det!

För att komma igång, skapa en mapp som heter middleware i projektkatalogen, och i den här mappen, skapa en fil som heter errorHandler.js som definierar felhanteraren:

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

I vår middleware-funktion har vi gjort Express medveten om att detta inte är en grundläggande middleware-funktion, utan en felhanterare, genom att lägga till error parameter före de 3 grundparametrarna.

Nu kommer vi att använda felhanteraren i vår demo app.js och hantera det initiala felet med att hämta användare med felhanterarens mellanprogram, som visas nedan:


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);

Vi kan optimera vår kod ännu mer genom att skapa en sammanfattning kring try/catch logik. Vi kan uppnå detta genom att skapa en ny mapp i projektkatalogen som heter utils, och i den, skapa en fil som heter tryCatch.js.

Att abstrahera try-catch logik – vi kan definiera en funktion som accepterar en annan funktion (känd som styrenhet) som parameter och returnerar en async funktion som kommer att hålla en try/catch för alla mottagna kontroller.

Om ett fel uppstår i styrenheten fångas det i catch block och nästa funktion kallas:


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

Med try/catch abstraktion, kan vi refaktorera vår kod för att göra den mer kortfattad genom att hoppa över try-catch klausul uttryckligen när du hämtar användare i 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);
	})
);

Vi har framgångsrikt abstraherat bort try-catch-logiken och vår kod fungerar fortfarande som den gjorde tidigare.

Hantera valideringsfel i Express

För denna demo kommer vi att skapa en ny rutt i vår Express-app för inloggning – för att validera ett användar-ID vid inloggning. Först kommer vi att installera joi paket, för att hjälpa till med att skapa ett schema, med vilket vi kan upprätthålla krav:

$ npm i joi

Skapa sedan ett schema som är en Joi.object med en userId som måste vara ett nummer och är obligatoriskt – vilket innebär att begäran måste matcha ett objekt med ett användar-ID på.

Vi kan använda validate() metod i schemaobjektet för att validera varje indata mot schemat:


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

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

Om ett tomt föremål förs in i validate() metoden, skulle felet hanteras elegant och felmeddelandet skulle skickas till klienten:

På konsolen får vi även tillgång till en details array som innehåller olika detaljer om felet som skulle kunna kommuniceras till användaren om det skulle behövas.

För att specifikt hantera valideringsfel på ett sådant sätt att lämplig feldetalj per valideringsfel skickas, kan mellanvaran för felhanteraren omfaktoreras:


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;

Med errorHandler.js nu anpassad, när vi gör samma begäran med ett tomt objekt som skickas till validate() metod:

Guide till undantagshantering i Express PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Vi har nu tillgång till ett anpassat objekt som returnerar meddelanden på ett mer läsbart/vänligt sätt. På så sätt kan vi skicka och hantera olika typer av fel baserat på vilken typ av fel som kommer in.

Slutsats

I den här guiden gick vi igenom alla aspekter av Express.js felhantering, inklusive hur synkron och asynkron kod hanteras som standard, hur du gör dina egna felklasser, hur du skriver anpassade felhanteringsfunktioner för mellanprogram och tillhandahåller next som sista fångsthanterare

Som med alla uppgifter där ute, finns det också bästa praxis under utveckling som inkluderar effektiv felhantering, och idag har vi lärt oss hur vi kan hantera fel i en Express-app på ett robust sätt.

Att hantera fel korrekt innebär inte bara att man minskar utvecklingstiden genom att enkelt hitta buggar och fel utan också att man utvecklar en robust kodbas för storskaliga applikationer. I den här guiden har vi sett hur man ställer in mellanprogram för att hantera driftsfel. Några andra sätt att förbättra felhanteringen inkluderar: att inte skicka stackspår, stoppa processer för att hantera ouppfångade undantag, tillhandahålla lämpliga felmeddelanden, skicka felloggar och ställa in en klass som utökar Error klass.

Jag hoppas att exemplen jag använde i den här handledningen var roliga för dig. Jag täckte olika scenarier som du potentiellt kan stöta på när du skriver en Express-applikation för användning i den verkliga världen om felhantering. Snälla, låt mig veta om det är något jag missat. Det kommer att gynna oss och hjälpa mig att lära mig mer också. Ha en bra dag och tack för att du läser.

Du kan referera till all källkod som används i artikeln om Github.

Ytterligare resurser

Tidsstämpel:

Mer från Stackabuse