# Error Handling — Fastify: Building High-Performance Node.js APIs

Source: https://www.skillbyai.com/en/fastify/ff-error-handling

> Throw errors in async handlers, define custom error classes and control error responses.

## Error handling strategy

Throw errors in route handlers; Fastify's built-in error handler catches them and returns appropriate status codes and responses.

## Custom error class

Define a custom error class to control status codes and payloads.

```javascript
class AppError extends Error {
  constructor(message, statusCode = 500) {
    super(message);
    this.statusCode = statusCode;
  }
}

fastify.get('/users/:id', async (req) => {
  const user = await findUser(req.params.id);
  if (!user) {
    throw new AppError('User not found', 404);
  }
  return user;
});

fastify.setErrorHandler((err, req, reply) => {
  const statusCode = err.statusCode || 500;
  reply.status(statusCode).send({ error: err.message });
});
```

## Async error handling

Fastify automatically catches errors thrown in async handlers—no need for try/catch wrappers.

## A custom error handler

`setErrorHandler` catches errors thrown in handlers and hooks.

- `error.statusCode` is set by `reply.code` or validation failures.
- Return a consistent JSON shape.

```js
const fastify = require('fastify')();

fastify.setErrorHandler((error, request, reply) => {
  reply.code(error.statusCode || 500).send({
    ok: false,
    message: error.message
  });
});

fastify.get('/boom', async () => {
  throw new Error('kaboom');
});
```

Quick check

**Quiz:** What status does Fastify use for an uncaught `throw new Error('x')` in a handler by default?

- [ ] 400
- [x] 500
- [ ] 200

*Answer:* 500. Errors without a statusCode become 500 Internal Server Error.
