Good Code
The good version uses an async handler and lets thrown errors move to the central error handler.
Lesson 05
Let async route failures reach the Express error pipeline instead of becoming unhandled work.
import { Router } from "express";
import { NotFoundError } from "../errors";
export function createReviewsRouter(service: ReviewsService) {
const router = Router();
router.get("/:id", async (req, res) => {
// Thrown async errors flow to the central error handler.
const review = await service.getReview(req.params.id);
if (!review) {
throw new NotFoundError("Review not found.");
}
res.json({ data: review });
});
return router;
}import { Router } from "express";
export function createReviewsRouter(service: ReviewsService) {
const router = Router();
router.get("/:id", (req, res) => {
// This promise chain is not returned or caught.
service.getReview(req.params.id).then((review) => {
if (!review) {
res.status(404).json({ error: "Review not found." });
return;
}
res.json({ data: review });
});
});
return router;
}The good version uses an async handler and lets thrown errors move to the central error handler.
The bad version starts promise work without returning or catching it, so service failures can become unhandled while the request remains unfinished.