Error handling

Development

One of the nice things about working with a server-side framework is the built-in exception handling you get for free. For example, Laravel ships with Ignition, a beautiful error reporting tool which displays a nicely formatted stack trace in local development.

The challenge is, if you're making an XHR request (which Inertia does), and you hit a server-side error, you're typically left digging through the network tab in your browser's devtools.

Inertia solves this by showing all non-Inertia responses in a modal. Meaning you get the same beautiful error-reporting, even though you've made that request over XHR!

Loading…
Note, the modal behaviour is only intended for development purposes.

Production

In production you'll want to return a proper Inertia error response instead of relying on the modal behaviour. To do this you'll need to update your framework's default exception handler to return a custom error page.

use Throwable;
use Inertia\Inertia;

/**
 * Prepare exception for rendering.
 *
 * @param  \Throwable  $e
 * @return \Throwable
 */
public function render($request, Throwable $e)
{
    $response = parent::render($request, $e);

    if (!app()->environment(['local', 'testing']) && in_array($response->status(), [500, 503, 404, 403])) {
        return Inertia::render('Error', ['status' => $response->status()])
            ->toResponse($request)
            ->setStatusCode($response->status());
    } else if ($response->status() === 419) {
        return back()->with([
            'message' => 'The page expired, please try again.',
        ]);
    }

    return $response;
}
Extend the render() method in your App\Exceptions\Handler.php.

Notice how we're returning an `Error` page component in the example above. You'll need to actually create this. Here's an example error page component you can use as a starting point.

<template>
  <div>
    <H1>{{ title }}</H1>
    <div>{{ description }}</div>
  </div>
</template>

<script>
export default {
  props: {
    status: Number,
  },
  computed: {
    title() {
      return {
        503: '503: Service Unavailable',
        500: '500: Server Error',
        404: '404: Page Not Found',
        403: '403: Forbidden',
      }[this.status]
    },
    description() {
      return {
        503: 'Sorry, we are doing some maintenance. Please check back soon.',
        500: 'Whoops, something went wrong on our servers.',
        404: 'Sorry, the page you are looking for could not be found.',
        403: 'Sorry, you are forbidden from accessing this page.',
      }[this.status]
    },
  },
}
</script>