Errors
Introduction
The JSON API spec defines error objects that are returned
in the top-level errors
member of the response body. This package automatically handles converting
common Laravel exceptions to these error objects, for example HTTP exceptions and validation exceptions.
In addition, it provides the ability for you to return custom errors as needed. This chapter describes how to return your own error responses.
Creating Error Objects
Error objects can be constructed from array key/value pairs using the static fromArray
method on
the package's error class. All the keys described in the specification's
error objects chapter are supported.
For example:
use CloudCreativity\LaravelJsonApi\Document\Error\Error;
$error = Error::fromArray([
'id' => '91053382-7c00-45eb-bdcc-8359d03debbb',
'status' => '500',
'code' => 'unexpected',
'title' => 'Unexpected Error',
'detail' => 'Something went wrong.',
'meta' => ['foo' => 'bar'],
]);
Controller Hooks
All controller hooks can return a HTTP response that will be used instead of the normal response generated by the controller. This means you can use these controller hooks to return JSON API error responses.
The JsonApiController
has a responses factory that can create error responses. This can be used
to return an error response in a controller hook, as demonstrated in the following example:
use CloudCreativity\LaravelJsonApi\Document\Error\Error;
use CloudCreativity\LaravelJsonApi\Http\Controllers\JsonApiController;
class PaymentController extends JsonApiController
{
protected function creating()
{
if (/** some condition */) {
return $this->reply()->errors(Error::fromArray([
'title' => 'Payment Required',
'detail' => 'Your card has expired.',
'status' => '402',
]));
}
}
}
And the response given would be the following:
HTTP/1.1 402 Payment Required
Content-Type: application/vnd.api+json
{
"errors": [
{
"title": "Payment Required",
"detail": "Your card has expired."
"status": "402"
}
]
}
You can pass either a single error object, or an array of error objects to the errors()
reply method.
The HTTP status of the response will be calculated from the status in the error objects.
Throwing Errors
It is also possible to throw a JsonApiException
from anywhere in your code. This will be converted
to a JSON API response. For example:
use CloudCreativity\LaravelJsonApi\Document\Error\Error;
use CloudCreativity\LaravelJsonApi\Exceptions\JsonApiException;
try {
dispatchNow(new ChargeCard($token));
} catch (\App\PaymentException $ex) {
$error = Error::fromArray([
'title' => 'Payment Required',
'detail' => $ex->getMessage(),
'status' => '402',
]);
throw new JsonApiException($error, $ex);
}
The JSON API exception takes three arguments:
- An error object or an array of error objects.
- The previous exception (optional)
- Additional headers for the response (optional).
You can also fluently construct a JSON API exception with headers:
use CloudCreativity\LaravelJsonApi\Document\Error\Error;
use CloudCreativity\LaravelJsonApi\Exceptions\JsonApiException;
throw JsonApiException::make(Error::fromArray([
'status' => '418',
'title' => "I'm a Teapot"
]))->withHeaders(['X-Foo' => 'Bar']);