Skip to main content

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:

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.
  • 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)

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.