Error handling yang baik membuat API kamu lebih robust dan user-friendly.
Try/catch di route handler:
app.get("/users/:id", (req, res) => {
try {
const user = db.prepare("SELECT * FROM users WHERE id = ?").get(req.params.id);
if (!user) return res.status(404).json({ error: "User not found" });
res.json(user);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Internal server error" });
}
});
Error middleware (centralized):
// Letakkan SETELAH semua route
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: err.message || "Internal server error",
});
});
Format error yang konsisten:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": [
{ "field": "email", "message": "Required" }
]
}
}
Tips:
- Jangan expose stack trace di production
- Log error untuk debugging (gunakan logger seperti pino/winston)
- Gunakan status code yang tepat (400 vs 500)
- Berikan pesan error yang actionable untuk client
Async Error Wrapper Pattern:
Di Express 4, error yang di-throw dari async route handler tidak otomatis tertangkap oleh error middleware — kamu harus selalu try/catch dan memanggil next(err):
app.get("/users/:id", async (req, res, next) => {
try {
const user = await findUser(req.params.id);
res.json(user);
} catch (err) {
next(err); // wajib, kalau tidak error hilang
}
});
Menulis try/catch di setiap route melelahkan. Solusinya: wrapper asyncHandler.
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
// Pakai:
app.get("/users/:id", asyncHandler(async (req, res) => {
const user = await findUser(req.params.id);
res.json(user); // error apapun otomatis ke error middleware
}));
Wrapper ini membungkus handler async dengan Promise.resolve().catch(next), sehingga rejection otomatis dioper ke next(). Kode jadi lebih bersih.
Express 5 sudah menangani async error secara otomatis — kamu tidak perlu lagi wrapper:
// Express 5: langsung throw, ter-handle otomatis
app.get("/users/:id", async (req, res) => {
const user = await findUser(req.params.id); // jika reject, ke error middleware
res.json(user);
});
Di dunia nyata, banyak project masih di Express 4 → tetap perlu asyncHandler atau library seperti express-async-errors.