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') && 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>