21 octobre 2021 173.411K

Formation Laravel : Exceptions

Si vous êtes arrivés jusqu’à ce chapitre vous avez déjà du vous confronter à des messages d’erreur vous retournant des exceptions. :p
Ces exceptions sont intégrés de base dans Laravel, ici nous allons voir comment créer nos propres exceptions.

Petite précision : Ici nous parlerons bien d’Exceptions et non d’Erreurs ! Si vous souhaitez voir comment retourner une erreur avec Laravel je vous invite à vous rendre dans la dernière partie du chapitre sur les controllers.

1. Les Exceptions en PHP

Dans cette première partie je présente et explique rapidement les exceptions en PHP. Si vous êtes déjà bien familiarisé avec les exceptions vous pouvez sauter directement cette partie 1 et descendre jusqu’à la partie 2 où nous parlerons des erreurs et exceptions dans Laravel.

Pourquoi renvoyer des exceptions ?

Les exceptions sont générées lorsqu’une erreur survient lors de l’exécution du code. Les exceptions que vous avez vu jusqu’à maintenant sont surtout là pour vous aider, vous, en tant que développeur pour corriger vos erreurs de code.

Mais, une fois votre application web mise en production, une exception peut également se produire par les actions d’un utilisateur et celui-ci n’aura pas accès au message de l’exception car votre variable d’environnement 'APP_DEBUG' sera en false et qu’il est hors de question que des utilisateurs puissent voir ces messages d’erreurs PHP qui délivrent parfois bien trop d’informations !

Il n’est pas non plus pensable de laisser nos utilisateurs devant une page blanche sans comprendre ce qu’il se passe. Si nous voulons donc leur faire comprendre l’erreur qui s’est produite nous devons attraper cette erreur pour pouvoir la manipuler par la suite. Ce que PHP nous permet de faire grâce aux blocs try {}catch {} et finally {} (ce dernier bloc est beaucoup moins utilisé que les 2 autres) :

try {
    // essaie de faire ça
} catch (Exception $e) {
    // notre exception $e est attrapée
} finally {
    // execute toujours ce code à la suite de try et catch (qu'il y ait exception ou pas)
}
// puis continue l'execution normale.

Vous ne verrez pas souvent ce bloc finally {} mais je vous en parle quand même. Concernant les deux autres blocs try {} et catch {} ceux-ci permettent donc respectivement d’entourer une partie du code où une exception est susceptible d’apparaitre, puis d’attraper cette exception pour en faire un objet.

Après avoir mis en place le bloc try et catch il nous faut maintenant lancer l’exception avec throw qui nous permettra de créer une instance d’Exception. On y passe en paramètre le message que l’on souhaite retourner.

throw new Exception('Message de mon exception');

Voici un petit exemple pratique : j’ai une fonction qui prend en paramètre une lettre et qui retourne sa position dans l’alphabet (ou son index pour les férus de tableaux :p)

function posLetter($letter) {
    if(!is_string($letter)) {
        throw new Exception('Le paramètre n\'est pas de type "string".');
    }
    $alphabet = range('a', 'z');
    $pos = array_search(strtolower($letter), $alphabet) +1;
    return "La Position de $letter est : ".$pos."<br>";
}

try {
    echo posLetter('a');
    echo posLetter('E');
    echo posLetter(1);
} catch (Exception $e) {
    echo "Erreur : ".$e->getMessage().'<br>';
}

On a donc une fonction posLetter qui retourne la position de la lettre donnée en paramètre. Dans cette fonction on place une condition : si le paramètre n’est pas de type String on lance une exception avec en message « Le paramètre n’est pas de type “string” ».

Voici ce que cela retourne :

La Position de a est : 1
La Position de B est : 2
Erreur : Le paramètre n'est pas de type "string".

D’autres Class d’exceptions existent, elles sont toutes extends de la Class « mère » Exception.

Exception
    ClosedGeneratorException
    DOMException
    ErrorException
    IntlException
    LogicException
        BadFunctionCallException
            BadMethodCallException
        DomainException
        InvalidArgumentException
        LengthException
        OutOfRangeException
    PharException
    ReflectionException
    RuntimeException
        OutOfBoundsException
        OverflowException
        PDOException
        RangeException
        UnderflowException
        UnexpectedValueException
    SodiumException

Vous pouvez vous rendre sur la documentation de PHP pour en savoir un peu plus sur les exceptions.

En plus de ces exceptions directement utilisables nativement en PHP, Laravel permet de créer ses propres exceptions.

2. Créer une Exception avec Laravel

Il vous est possible de créer vos propres exceptions dans Laravel grâce à la commande suivante :

php artisan make:exception CustomException

Les exceptions sont traitées par la class Handler située dans le namespace : App\Exception.

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        return parent::render($request, $exception);
    }
}

Cette class extends une autre Class Handler qui use les Class natives PHP Exception et Throwable. On peut également remarquer qu’elle contient 2 méthodes :
report() : permet de faire des logs de l’exception ainsi que de les envoyer vers des services extérieurs (par exemple par mail).
render() : permet de faire un rendu de l’exception en réponse HTTP.

Reprenons donc notre exception créée précédemment et faisons-en une class d’Exception :

php artisan make:exception CustomException
<?php

namespace App\Exceptions;

use Exception;

class CustomException extends Exception
{
    /**
     * Report the exception.
     *
     * @return void
     */
    public function report()
    {
        \Log::debug('Une erreur est survenue');
    }

    /**
     * Render the exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request
     * @return \Illuminate\Http\Response
     */
    public function render($request)
    {
        return response()->view('error', [], 500);
    }
}

Ici, la fonction nous permet donc de rapporter cette erreur dans nos logs qui se trouvent dans storage/logs.

Dans notre code nous allons maintenant faire appel à cette Exception :

function indexLetter($letter) {
    if(!is_string($letter)) {
        throw new App\Exceptions\CustomException('Le paramètre n\'est pas de type "string".');
    }
    $alphabet = range('a', 'z');
    $pos = array_search(strtolower($letter), $alphabet) +1;
    return "La Position de $letter est : ".$pos."<br&:gt;";
}

try {
    echo indexLetter('a');
    echo indexLetter('E');
    echo indexLetter(1);
} catch (App\Exceptions\CustomException $e) {
    return $e->render($request);
}

Maintenant la seconde méthode de notre Class CustomException nous permet de retourner un rendu (render) avec une vue et un code_status 500 qui correspond à une erreur serveur : « Internal Server Error ». Pour y avoir accès dans notre code il nous suffit d’utiliser cette méthode sur notre objet $e dans notre bloc catch :

return $e->render($request);

Besoin d'une formation personalisée ?

Avis

4,9
Rated 4.9 out of 5
Excellent88%
Splendide !12%
Sympa0%
Sans plus0%
Pas terrible0%

Pas de titre

Rated 5 out of 5
15 avril 2024

cool

paul

Pas de titre

Rated 5 out of 5
2 avril 2024
Evelyn

Pas de titre

Rated 4 out of 5
2 avril 2024

Merci beaucoup pour ce cour.

adil

Pas de titre

Rated 5 out of 5
7 mars 2024

super

hajar

Pas de titre

Rated 5 out of 5
21 juin 2023

Merci énormément je suis sur exciter à cause de ce cours

Kassi Patrick