Exception Handling

The toolkit provides an exception handler that renders all exceptions as JSON:API error responses, so your API never returns HTML error pages.

Setup

Register the handler in bootstrap/app.php:

use BlueBeetle\ApiToolkit\Exceptions\ConfigureExceptionHandler;

->withExceptions(new ConfigureExceptionHandler())

Exception Mapping

ExceptionStatusTitle
AuthenticationException401Unauthorized
ValidationException422Validation Error (with field pointers)
ModelNotFoundException404Not Found
NotFoundHttpException404Not Found
MethodNotAllowedHttpException404Not Found
RouteNotFoundException404Not Found
QueryException400Bad Request
LazyLoadingViolationException400Bad Request
IdempotencyExceptionvariesIdempotency Error
Domain exceptions (configurable)400Bad Request
Everything else500Internal Server Error

Validation Errors

Validation exceptions are rendered with source pointers for each field:

{
  "errors": [
    {
      "status": "422",
      "code": "validation_error",
      "title": "Validation Error",
      "detail": "The name field is required.",
      "source": {
        "pointer": "/name"
      }
    },
    {
      "status": "422",
      "code": "validation_error",
      "title": "Validation Error",
      "detail": "The email must be a valid email address.",
      "source": {
        "pointer": "/email"
      }
    }
  ]
}

Domain Exceptions

Register your application's domain exceptions so they're treated as 400 errors instead of 500s:

// config/api-toolkit.php
'exceptions' => [
    'domain' => [
        \App\Exceptions\InsufficientFundsException::class,
        \App\Exceptions\OrderAlreadyShippedException::class,
    ],
],

Debug Mode

When APP_DEBUG is true, error responses include additional debug information:

{
  "errors": [
    {
      "status": "500",
      "code": "api_error",
      "title": "Internal Server Error",
      "detail": "SQLSTATE[42S22]: Column not found...",
      "meta": {
        "debug": {
          "line": 42,
          "file": "/app/Http/Controllers/ProductController.php",
          "class": "Illuminate\\Database\\QueryException",
          "trace": [...]
        }
      }
    }
  ]
}

Suppressing Reports

Prevent certain exceptions from being logged:

// config/api-toolkit.php
'exceptions' => [
    'dont_report' => [
        \App\Exceptions\ExpectedBusinessException::class,
    ],
],