Skip to main content

Error Handling

We generally do not use try/catch in controllers. Instead, we let exceptions bubble up to the Global Exception Handler.

The Global Handler (app/Exceptions/Handler.ts)

This class catches all uncaught errors and formats them into a standardized JSON response:

{
"errors": [
{
"message": "Camera not found",
"code": "E_ROW_NOT_FOUND",
"status": 404
}
]
}

Custom Exceptions

BusinessException

Use this for logical errors (e.g., "Cannot delete a camera that is recording").

import BusinessException from "#exceptions/business_exception";

if (camera.isRecording) {
throw BusinessException.badRequest("Cannot delete active camera");
}

Available static methods:

  • .badRequest(message) -> 400
  • .notFound(message) -> 404
  • .forbidden(message) -> 403

Validation Errors

When VineJS validation fails, it automatically throws E_VALIDATION_ERROR (422), which is caught by the handler and formatted as a list of field-specific errors.