Autour de Laravel

Eviter le plantage de l'application suite à une erreur

Avatar de KYoann
KYoann

Bonjour à tous.

J'utilise le système intégré de notification de laravel qui fonctionne parfaitement pour envoyer des Emails d'alerte. Mais il peut arriver qu'un utilisateur ai mal saisi sont adresse, et dans le cas ou elle soit malformé le script de notification plante, et le reste des scripts qui suivent ne s'execute pas.

Exemple :

Swift_RfcComplianceException: Address in mailbox given [.mon.mail@outlook.com] does not comply with RFC 2822

Comment faire pour créer une exeption, que la notification ne fonctionne pas, sans pour autant bloquer le reste.

J'ai essayé d'englober l'execution de ma notification dans mon controller mais cela ne fait rien

try{
    $administrateur->notify(new Notif($data,$user));
} catch (Exception $e){
    Mail::to('erreur@kontas.fr')->send(new Erreur($e));
}

Merci

Posté il y a 1 mois
Avatar de bestmomo
bestmomo

Salut,

Le plus simple serait de valider l'email en amont.

Posté il y a 1 mois
Avatar de KYoann
KYoann

Une seule ou plusieurs fois ? ^^

Je suis complêtement d'accord avec toi. Mais j'aimerais bien être capable d'éviter que mon programme plante dans les moments un peut critiques.

Posté il y a 1 mois
Avatar de bestmomo
bestmomo

Notre forum begaie un peu en plus d'avoir perdu son certificat SSL :)

Pour ton souci le plus simple est d'intercepter l'erreur dans App\Exceptions\Handler.

Posté il y a 1 mois
Avatar de KYoann
KYoann

Salut, merci pour ta réponse, du coup j'ai enlever la possibilité d'envoyer de recevoir des notifications aux utilisateurs qui n'avaient pas valider leurs adresse Email.

Cela dis, j'ai regardé du côté des exceptions comme tu l'a sugeré et j'essai maintenant de recevoir un email pour m'avertir qu'un utilisateur à eu une erreur 500. Cela fonction bien, sauf que si l'application n'est pas en mode débug dans le fichier d'environnement (debug=false) au lieu de recevoir un message d'erreur complet, j'ai juste un truc générique

Mon Fichier handler

<?php

namespace App\Exceptions;

use App\Mail\ExceptionOccured;
use Illuminate\Support\Facades\Mail;
use Throwable;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

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.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     */
    public function report(Throwable $exception)
    {

        if ($this->shouldReport($exception)) {
            $this->sendEmail($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, Throwable $exception)
    {

        if ($exception instanceof \Illuminate\Session\TokenMismatchException) {

            return redirect('/login')->with('nok','Le formulaire de connexion a expiré, veuillez vous reconnecter');

        }

        return parent::render($request, $exception);
    }

    public function sendEmail(Throwable $e)
    {
        try {

            $html = ExceptionHandler::convertExceptionToResponse($e);

            Mail::to('mail@gmail.com')->send(new ExceptionOccured($html));

        } catch (Exception $ex) {
            Log::error($ex);
        }
    }
}

Ce que je reçois par Email:

Oops! An Error Occurred The server returned a "500 Internal Server Error". Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.

Avatar de bestmomo
bestmomo

Salut,

Regarde ici.

Avatar de KYoann
KYoann

Merci pour le lien,

Le souci c'est que la classe SymfonyExceptionHandler(); n'existe plus :/

Avatar de bestmomo
bestmomo
Avatar de KYoann
KYoann

Génial ca marche mieux, cela dit j'ai fait quelques aménagment dans le code proposé, car la méthode pour récupérer l'url ne marcher pas, de plus je récupére des informations sur l'utilisateur qui à rencontré l'erreur.

Dans le Handler.php

public function sendEmail(Throwable $exception)
    {

        try {

            $e = FlattenException::create($exception);
            $handler = new HtmlErrorRenderer(true);
            $content = $handler->getBody($e);
            $url = URL::current();

            Mail::to('mon@mail.com')->send(new ExceptionOccured($content,$url));

        } catch (Throwable $exception) {
            Log::error($exception);
        }
    }

Dans la class mail :

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ExceptionOccured extends Mailable
{
    use Queueable, SerializesModels;

    public $content;
    public $url;

    /**
     * Create a new message instance.
     *
     * @param $content
     * @param $url
     */
    public function __construct($content,$url)
    {
        $this->content = $content;
        $this->url = $url;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build(): ExceptionOccured
    {
        return $this->from('autre@mail.com', $name = 'machin truc')
            ->subject('Erreur 500 a '.$this->url)
            ->view('mails.Erreur')
            ->with(['erreur' => $this->content]);
    }
}

Et enfin la vue en question

<h3>Utilisateur :</h3>
@if(Auth::check())
    - Id : {{ Auth::User()->id }} <br>
    - Nom : {{ Auth::User()->nom }} <br>
    - Prénom : {{ Auth::User()->prenom }} <br>
    - Email : {{ Auth::User()->email }} <br>
    - Type : {{ Auth::User()->type }} <br>
    - Date de création du compte {{ Auth::User()->created_at->format('d-m-Y H:i') }} <br>
@else
    - non connecté
@endif


<h3>Erreur :</h3>
{!! $content !!}

Vous ne pouvez pas répondre à ce sujet.