Gestion des erreurs
Fait partie de la section Les bases d’Express du Journey Node.js de Coddy. Leçon 15 sur 20.
Lorsqu’une route lève une erreur, Express répond avec sa propre page d’erreur, qui n’est pas au format JSON et affiche des détails qui vous sont destinés.
app.get('/api/fines/:member', (req, res) => {
throw new Error('Fines database is down');
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Try again later' });
});Un middleware à quatre arguments, (err, req, res, next), est un gestionnaire d’erreurs. Express compte les arguments : avec trois arguments, il s’agit d’un middleware ordinaire, qui est ignoré en cas d’erreur. Lorsqu’une route lève une erreur, Express ignore les middlewares ordinaires et appelle le gestionnaire d’erreurs en lui transmettant l’erreur. Ajoutez-le en dernier, après le gestionnaire 404. Consignez les détails pour vous-même ; envoyez un court message au client.
Un ?by= incorrect est une erreur du visiteur, il reçoit donc toujours un code 400. Une erreur concerne ce que le visiteur ne peut pas corriger, par exemple une recette enregistrée sans le nombre de portions.
Défi
FacileGET /api/recipes/:id/scale?by=2renvoie{ "title", "servings" }, avec le nombre de portions multiplié.- Un facteur qui n’est pas un nombre positif :
400avec{ "error": "Scale by a positive number" }. - Une recette sans
servingsdéclencheRecipe <id> has no servings. - Un gestionnaire d’erreurs consigne l’erreur et renvoie
500avec{ "error": "Something went wrong" }.
Envoyez ?by=2 et ?by=lots. Ensuite, envoyez { "title": "Toast" } à /api/recipes, puis ajustez les quantités de la recette 5.
Essayez vous-même
import express from 'express';
import { randomUUID } from 'node:crypto';
import { recipes } from './data.js';
const app = express();
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
app.use((req, res, next) => {
res.set('X-Request-Id', randomUUID());
next();
});
app.use(express.json());
app.use(express.static('public'));
const escapeHtml = (text) =>
text
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"');
app.get('/', (req, res) => {
const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});
// type('text') envoie du texte brut, donc chaque titre apparaît sur sa propre ligne.
app.get('/recipes', (req, res) => {
const { tag } = req.query;
const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});
app.get('/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).send('No such recipe');
return;
}
res.send(recipe.title);
});
app.get('/api/recipes', (req, res) => {
res.json(recipes);
});
app.get('/api/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).json({ error: 'No such recipe' });
return;
}
res.json(recipe);
});
app.post('/api/recipes', (req, res) => {
const { title, tags } = req.body;
if (!title) {
res.status(400).json({ error: 'A recipe needs a title' });
return;
}
const recipe = { id: recipes.length + 1, title, tags: tags ?? [] };
recipes.push(recipe);
res.status(201).json(recipe);
});
app.get('/about', (req, res) => {
res.send('Recipe Box collects family recipes.');
});
app.get('/menu', (req, res) => {
res.redirect(301, '/recipes');
});
app.get('/menu/:id', (req, res) => {
res.redirect(301, `/recipes/${req.params.id}`);
});
app.use((req, res) => {
if (req.path.startsWith('/api/')) {
res.status(404).json({ error: 'Not found' });
return;
}
res.status(404).send('<h1>Page not found</h1><p><a href="/">Back to Recipe Box</a></p>');
});
app.listen(3000, () => {
console.log('Recipe Box is running on port 3000');
});
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Les bases d’Express
1Votre premier serveur
Bonjour, ExpressLe module httpPlus de routesParamètres de route3Middleware
Votre premier middleware