Labs ICT
โญ Pro Login

Error Handling

Try/catch, error types, and graceful failures.

Try/Catch for Async Code

Use try/catch with async/await to handle errors gracefully. You can check error properties like err.code or use instanceof to handle different error types.

async function processFile(filename) {
  try {
    const data = await fs.readFile(filename, "utf-8");
    const parsed = JSON.parse(data);
    return parsed;
  } catch (err) {
    if (err.code === "ENOENT") {
      console.error("File not found:", filename);
    } else if (err instanceof SyntaxError) {
      console.error("Invalid JSON in file");
    } else {
      throw err;  // Re-throw unknown errors
    }
  }
}

Custom Error Classes

Create custom error classes to represent specific error conditions. This makes it easy to throw meaningful errors with status codes and extra context.

class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
    this.statusCode = 400;
  }
}

class NotFoundError extends Error {
  constructor(resource) {
    super(`${resource} not found`);
    this.name = "NotFoundError";
    this.statusCode = 404;
  }
}

Express Error Handling

Express error-handling middleware uses a 4-parameter signature. Use the error's statusCode property to send the right HTTP status. In async routes, catch errors and pass them to next().

// Error handling middleware (must have 4 parameters)
app.use((err, req, res, next) => {
  console.error(err.stack);
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    error: {
      message: err.message,
      ...(process.env.NODE_ENV === "development" && { stack: err.stack })
    }
  });
});

// Throw errors in async routes
app.get("/api/users/:id", async (req, res, next) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) throw new NotFoundError("User");
    res.json(user);
  } catch (err) {
    next(err);
  }
});

Golden Rule: Always handle errors. Unhandled Promise rejections and uncaught exceptions crash your Node.js process. Use process.on("unhandledRejection") as a safety net.

Try it Yourself โ†’

๐Ÿงช Quick Quiz

How do you handle errors in async functions?