Les pages d'erreurs avec Laravel et InertiaJS
3 min read

Les pages d'erreurs avec Laravel et InertiaJS

Comment personnaliser les pages d'erreurs avec Laravel et InertiaJs ? Je vous explique tout !
Les pages d'erreurs avec Laravel et InertiaJS

Laravel gère automatiquement l'affichage de pages d'erreur. Elles sont détaillées en développement et contiennent des informations sur les causes de l'erreur. En production, elles sont très génériques et ne contiennent qu'un message, ce qui évite toute fuite de données.

En ajoutant Inertia, le fonctionnement par défaut de Laravel ne convient pas tout à fait. Comme les erreurs ne sont pas des réponses Inertia, elles sont ouvertes dans une modale, ce qui n'a pas trop de sens.

On va modifier le fonctionnement pour avoir une vraie redirection et afficher une page personnalisée !

Si Laravel est une technologie qui vous intéresse, je prépare un Compendium sur le sujet, il est disponible en Early Access aux inscrits sur mon site :

EARLY ACCESS - Compendium Laravel
Laravel est un framework PHP tout-en-un qui propose de nombreux éléments pour les développeurs d’application web et qui est très orienté. Il se veut accessible aux débutants et developer-friendly avec notamment des outils reconnus comme Eloquent.

Afficher une réponse Inertia comme erreur Laravel

La documentation d'Inertia nous indique la démarche à suivre. On ajoute une fonction render à notre App\Exception\Handler.php, la même classe qu'on modifie si on veut ajouter un outil comme Sentry ou Flare.

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;
}

Dans cette fonction, on récupère la réponse par défaut de Laravel, si on est en développement, on la renvoie simplement et on aura un affichage de la vue d'Ignition dans une modale. En production, on renvoie une réponse Inertia qu'on va pouvoir personnaliser.

Comme à chaque fois avec Inertia, on indique dans Inertia::render le nom du composant que l'on veut afficher. Dans notre exemple, il s'agit du fichier resources/js/Pages/Error.vue.

Ensuite, comme il s'agit d'une réponse Inertia classique et d'un composant Vue, on peut faire tout ce qu'on veut : passer des données du serveur en props, traduire le contenu, etc.

<template>
    <app-layout :public-site="true">
        <div v-if="status === 404">
            <div class="container">
                <div>
                    <div>
                        <h1>404</h1>
                        <h2>Vous êtes perdu... ?</h2><br>
                        <p>Ne vous inquiétez pas...<br/>
                            <b>Nous pouvons tout de même vous aider à trouver une maison !</b></p>
                        <a :href="route('find-a-home')" class="mt-4">Trouver une maison maintenant !</a>
                    </div>
                </div>
            </div>
        </div>
        <div v-else>
            <h1>{{ title }}</h1>
            <div>{{ description }}</div>
        </div>
    </app-layout>
</template>

<script>
import AppLayout from "@/Layouts/AppLayout";
export default {
    components: {AppLayout},
    props: {
        status: Number,
    },
    computed: {
        title() {
            return {
                503: '503: Service Indisponible',
                500: '500: Erreur',
                403: '403: Accès refusé',
            }[this.status]
        },
        description() {
            return {
                503: "Désolé, nous sommes en train d'effectuer une maintenance. Revenez plus tard.",
                500: 'Oups, une erreur est survenue.',
                403: "Désolé, vous n'avez pas accès à cette page.",
            }[this.status]
        },
    },
}
</script>

Vous aimez mes articles? Inscrivez-vous pour être alerté des nouveautés.