Installation Add the package via Composer:
composer require laravel-json-api/exceptions
Publish the config (if needed):
php artisan vendor:publish --provider="LaravelJsonApi\Exceptions\ExceptionsServiceProvider"
Basic Usage
Throw a JsonApiException to return standardized JSON:API error responses:
use LaravelJsonApi\Exceptions\JsonApiException;
throw new JsonApiException('Resource not found', 404, ['id' => '123']);
This automatically formats the response as:
{
"errors": [
{
"status": "404",
"title": "Resource not found",
"detail": null,
"source": {
"pointer": "/data/123"
}
}
]
}
First Use Case
Replace generic HttpException responses in controllers with JsonApiException for consistent API error formatting.
Controller-Level Errors
Replace abort(404) with:
throw new JsonApiException('Not found', 404, ['id' => $request->route('id')]);
Validation Errors
Use JsonApiValidationException for form validation:
use LaravelJsonApi\Exceptions\JsonApiValidationException;
$validator = Validator::make($request->all(), ['email' => 'required|email']);
if ($validator->fails()) {
throw new JsonApiValidationException($validator);
}
Custom Error Types
Extend JsonApiException for domain-specific errors:
class PaymentFailedException extends JsonApiException
{
public function __construct($message, $paymentId)
{
parent::__construct($message, 402, ['id' => $paymentId]);
}
}
Middleware Integration Catch exceptions in middleware to log or transform errors:
public function handle($request, Closure $next)
{
try {
return $next($request);
} catch (JsonApiException $e) {
// Custom logic (e.g., logging)
return response()->json($e->toArray(), $e->getStatusCode());
}
}
laravel-json-api/v5 for consistent error responses alongside resource serialization.JsonApiException in tests to assert error formats:
$this->expectException(JsonApiException::class);
$this->expectExceptionMessage('Not found');
Missing source Pointer
If source data (e.g., id) is omitted, the error lacks context. Always include identifiers:
// Bad: No pointer to locate the error.
throw new JsonApiException('Invalid', 400);
// Good: Includes `id` for debugging.
throw new JsonApiException('Invalid', 400, ['id' => $userId]);
Overriding Default Config
The package uses config('jsonapi-exceptions') for defaults (e.g., include_stacktrace). Ensure your .env or config/jsonapi-exceptions.php doesn’t conflict:
'include_stacktrace' => env('APP_DEBUG'), // Defaults to `false` in production.
Nested Exceptions
Avoid wrapping JsonApiException in other exceptions (e.g., Handler classes). Let the exception propagate directly.
include_stacktrace in config for development:
'include_stacktrace' => true,
Log::error('JSON:API Error', ['exception' => $e]);
Custom Error Formats
Override toArray() in a subclass:
class CustomException extends JsonApiException
{
public function toArray(): array
{
return [
'errors' => [
[
'status' => $this->getStatusCode(),
'title' => $this->getMessage(),
'meta' => ['custom_field' => 'value'] // Add custom data
]
]
];
}
}
Global Exception Handler
Use Laravel’s App\Exceptions\Handler to centralize error formatting:
public function render($request, Throwable $exception)
{
if ($exception instanceof JsonApiException) {
return response()->json($exception->toArray(), $exception->getStatusCode());
}
return parent::render($request, $exception);
}
Localization Localize error messages via Laravel’s translation system:
throw new JsonApiException(__('validation.required', ['attribute' => 'email']), 400);
How can I help you explore Laravel packages today?