> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pyqdeck.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Standardized error handling and response formatting in PyqDeck

## Hierarchy

PyqDeck uses a custom error hierarchy based on a `BaseError` class to ensure all errors have a consistent structure and status code.

### Custom Error Classes

Located in `backend/src/utils/errors/index.js`:

| Class               | HTTP Code | Purpose                                        |
| ------------------- | --------- | ---------------------------------------------- |
| `ValidationError`   | 400       | Invalid input data or Zod validation failure.  |
| `UnauthorizedError` | 401       | Missing or invalid authentication token.       |
| `ForbiddenError`    | 403       | Authenticated user lacks required permissions. |
| `NotFoundError`     | 404       | Resource does not exist.                       |
| `ConflictError`     | 409       | Resource already exists or state conflict.     |
| `RateLimitError`    | 429       | Too many requests from a single client.        |

## Global Error Handler

The `errorHandler` middleware (`backend/src/middlewares/errorHandler.js`) is the final stop for every request.

1. **Sentry Integration**: If `SENTRY_DSN` is configured, all 500+ errors are automatically reported to Sentry.
2. **Logging**: All errors are logged locally via the `loggerService`.
3. **Formatting**: Errors are transformed into a standard JSON structure using `errorFormatter`.
4. **Production Safety**: In production, stack traces are stripped from 500 errors to avoid leaking internal details.

## Response Formatters

We use two utility objects in `backend/src/utils/formatters/` to ensure the API always returns a predictable structure.

### Success Response (`successFormatter.js`)

Used for all non-error responses.

```javascript theme={null}
{
  "status": "success",
  "message": "Operation successful",
  "data": { ... },
  "code": 200
}
```

* `formatSuccess(data, message, code)`: For single objects or simple operations.
* `formatList(items, total, page, limit)`: specifically for paginated lists, adding a `pagination` metadata object.

### Error Response (`errorFormatter.js`)

```javascript theme={null}
{
  "status": "error",
  "message": "Resource not found",
  "code": "NOT_FOUND",
  "statusCode": 404
}
```

## Best Practices

* **Never `res.send()` directly**: Always use the formatters in controllers.
* **Throw, don't return**: In services and repositories, throw the appropriate `BaseError`. The `catchAsync` wrapper in controllers will automatically pass it to the global error handler.
* **Operational vs. Programmer Errors**: `BaseError` subclasses are considered "operational" (expected). Everything else is a "programmer error" and will result in a 500 status code.
