Error Handling — Node.js

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 = d

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:

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.

Yang akan kamu pelajari