Erreurs et structure de projet
Middleware d'erreur à quatre arguments, async/await, 404, variables d'environnement et arborescence maintenable.
Une API qui plante sur la première exception n'est pas utilisable. Express propose un canal dédié aux erreurs, à condition de respecter une signature précise.
🛡️ Le middleware d'erreur à quatre arguments
// middlewares/erreurs.js
export function gestionnaireErreurs(err, req, res, next) {
console.error(err);
const status = err.statusCode ?? 500;
res.status(status).json({
error: status === 500 ? "Erreur interne du serveur" : err.message,
});
}Express reconnaît un gestionnaire d'erreurs uniquement à son arité : quatre paramètres (err, req, res, next). En retirer un — même next, inutilisé — le transforme en middleware ordinaire qui ne recevra jamais les erreurs.
Il se déclare en dernier, après toutes les routes.
err.statusCode est la propriété native de Error en Node.js. err.status est une convention maison utilisée par certains frameworks. Les deux fonctionnent, mais err.statusCode est plus standard.
🚦 Déclencher une erreur
app.get("/api/articles/:id", (req, res, next) => {
const article = trouver(req.params.id);
if (!article) {
const err = new Error("Article introuvable");
err.statusCode = 404;
return next(err); // saut direct vers le gestionnaire d'erreurs
}
res.json(article);
});Passer un argument à next() court-circuite tous les middlewares normaux restants.
⏳ Erreurs asynchrones
Une exception levée dans une fonction async n'est pas capturée automatiquement par Express 4 : la promesse est rejetée sans que personne n'écoute.
app.get("/api/articles", async (req, res, next) => {
try {
const articles = await db.findAll();
res.json(articles);
} catch (err) {
next(err);
}
});Le wrapper évite de répéter le try/catch dans chaque contrôleur.
Express 5 transmet automatiquement les rejets de promesses au gestionnaire d'erreurs. Le wrapper reste néanmoins la solution portable et lisible.
🔍 Le 404 attrape-tout
Placé après les routes mais avant le gestionnaire d'erreurs :
app.use((req, res, next) => {
const err = new Error(`Route inconnue : ${req.method} ${req.originalUrl}`);
err.statusCode = 404;
next(err);
});
app.use(gestionnaireErreurs);Ainsi, 404 et 500 passent par le même formateur de réponse.
🔑 Variables d'environnement
Jamais de port, d'URL de base ni de secret en dur dans le code.
npm install dotenv# .env — à ajouter dans .gitignore
PORT=3000
NODE_ENV=development
DATABASE_URL=mongodb://localhost:27017/blog
JWT_SECRET=change-moiimport "dotenv/config";
const PORT = process.env.PORT ?? 3000;
if (!process.env.JWT_SECRET) {
throw new Error("JWT_SECRET manquant : vérifiez votre fichier .env");
}Bonnes pratiques :
- versionner un
.env.examplesans valeurs sensibles ; - vérifier au démarrage la présence des variables obligatoires ;
- masquer les détails techniques en production (
NODE_ENV === "production").
🗂️ Une structure qui tient dans le temps
src/
├── app.js # configuration Express (middlewares + montage des routes)
├── server.js # chargement .env + app.listen
├── config/
│ └── db.js
├── routes/
│ └── articles.routes.js
├── controllers/
│ └── articles.controller.js
├── services/
│ └── articles.service.js
├── middlewares/
│ ├── auth.js
│ └── erreurs.js
└── models/
└── article.model.jsSéparer app.js de server.js a un intérêt concret : les tests importent app et l'interrogent sans ouvrir de port.
// server.js
import "dotenv/config";
import app from "./app.js";
app.listen(process.env.PORT ?? 3000, () => console.log("API démarrée"));Répartition des responsabilités : la route déclare l'URL, le contrôleur lit req et construit res, le service contient la logique métier et parle au modèle.
✅ Points clés
- Quatre arguments, sinon ce n'est pas un gestionnaire d'erreurs.
next(err)saute directement au gestionnaire.- Les fonctions
asyncdemandenttry/catchou un wrapper. - Configuration par variables d'environnement,
.envhors du dépôt.
Express
Terminez le quiz du chapitre pour le marquer comme complété.
Requêtes et réponses
Exploiter l'objet req (params, query, body, headers) et construire des réponses avec res et les bons codes HTTP.
Atelier — monter une API Express pas à pas
Mise en pratique assistée : structurer un routeur express.Router, enchaîner les middlewares et protéger une route avec un middleware d'authentification maison.