Fehlerbehandlung
Teil des Abschnitts Express-Grundlagen der Node.js-Journey von Coddy. Lektion 15 von 20.
Wenn eine Route einen Fehler auslöst, antwortet Express mit einer eigenen Fehlerseite, die kein JSON ist und Details anzeigt, die für dich bestimmt sind.
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' });
});Eine Middleware mit vier Argumenten, (err, req, res, next), ist ein Fehler-Handler. Express zählt die Argumente: Bei drei handelt es sich um gewöhnliche Middleware, und Fehler überspringen sie. Wenn eine Route einen Fehler auslöst, überspringt Express die gewöhnliche Middleware und ruft den Fehler-Handler mit dem Fehler auf. Füge ihn zuletzt hinzu, nach dem 404-Handler. Protokolliere die Details für dich selbst; sende dem Client eine kurze Nachricht.
Ein ungültiges ?by= ist der Fehler des Besuchers und führt daher weiterhin zu einem 400-Statuscode. Ein Fehler betrifft etwas, das der Besucher nicht beheben kann, etwa ein Rezept, das ohne Angabe der Portionen gespeichert wurde.
Aufgabe
EinfachGET /api/recipes/:id/scale?by=2liefert{ "title", "servings" }, wobei die Anzahl der Portionen multipliziert wird.- Ein Faktor, der keine positive Zahl ist:
400mit{ "error": "Scale by a positive number" }. - Bei einem Rezept ohne
servingswirdRecipe <id> has no servingsausgelöst. - Ein Fehlerbehandler protokolliert den Fehler und antwortet mit
500und{ "error": "Something went wrong" }.
Sende ?by=2 und ?by=lots. Sende anschließend { "title": "Toast" } an /api/recipes und skaliere Rezept 5.
Probier es selbst
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') sendet Klartext, sodass jeder Titel in einer eigenen Zeile erscheint.
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');
});
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Express-Grundlagen
3Middleware
Dein erstes Middleware