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']);