Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 8: render exception as html for email

I upgraded my Laravel app to the latest version Laravel 8. My problem now is that I cannot figure out how to render an exception thrown by the app to html in order to send that html as an email.

My current code (that worked for Laravel 5) to render and send an exception within the App\Exceptions\Handler class:

public function sendEmail(Exception $exception)
{
    try {
        $e = FlattenException::create($exception);

        $handler = new SymfonyExceptionHandler();

        $html = $handler->getHtml($e);

        $routeName = URL::full();

        Mail::send(new ExceptionEmail($html, $routeName));

    } catch (Exception $ex) {
        if (env("APP_DEBUG") == true) {
            dd($ex);
        }
    }
}

The problem is that class \Symfony\Component\Debug\Exception\FlattenException does not exist anymore in my upgraded app.

What is the appropriate way to render exceptions as html now in Laravel 8?

Thank you very much in advance.

like image 894
LaDude Avatar asked Oct 28 '20 17:10

LaDude


People also ask

What is a Renderable exception?

While rendering an exception, Laravel checks if the exception class has a render() method, if so it just uses the output of this method to build the response, you can return anything from this method as you normally do within a controller method.

What is exception error in laravel?

HTTP Exceptions Some exceptions describe HTTP error codes from the server. For example, this may be a "page not found" error (404), an "unauthorized error" (401) or even a developer generated 500 error. In order to generate such a response from anywhere in your application, you may use the abort helper: abort(404);


1 Answers

Alright i managed to receive email, here is the code

Composer requirement

"require": {
    "php": "^7.3|^8.0",
    .....
    "jeremykenedy/laravel-exception-notifier": "^2.2",
    "laravel/framework": "^8.40",
    .....
},

app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use App\Mail\ExceptionOccurred;
use Exception;
use Throwable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpFoundation\Response;

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 = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }

    /**
     * Report or log an exception.
     *
     * @param Exception $e
     * @return void
     * @throws Throwable
     */
    public function report(Throwable $e)
    {
        if ($this->shouldReport($e)) {
            $this->sendEmail($e); // sends an email
        }
        parent::report($e);
    }
    /**
     * Render an exception into an HTTP response.
     *
     * @param Request $request
     * @param Throwable $e
     * @return Response
     *
     * @throws Throwable
     */
    public function render($request, Throwable $e): Response
    {
        return parent::render($request, $e);
    }

    public function sendEmail(Throwable $exception)
    {
        try {
            $e = FlattenException::createFromThrowable($exception);
            $handler = new HtmlErrorRenderer(true);
            $css = $handler->getStylesheet();
            $content = $handler->getBody($e);
            Mail::to('your_email_address_here')->send(new ExceptionOccurred($content,$css));
        } catch (Throwable $exception) {
            Log::error($exception);
        }
    }
}

app/Mail/ExceptionOccurred.php

<?php

namespace App\Mail;

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

class ExceptionOccurred extends Mailable
{
    use Queueable, SerializesModels;

    private $content;
    private $css;

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

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $emailsTo = str_getcsv(config('exceptions.emailExceptionsTo'), ',');
        $ccEmails = str_getcsv(config('exceptions.emailExceptionCCto'), ',');
        $bccEmails = str_getcsv(config('exceptions.emailExceptionBCCto'), ',');
        $fromSender = config('exceptions.emailExceptionFrom');
        $subject = config('exceptions.emailExceptionSubject');

        if ($emailsTo[0] === null) {
            $emailsTo = config('exceptions.emailExceptionsToDefault');
        }

        if ($ccEmails[0] === null) {
            $ccEmails = config('exceptions.emailExceptionCCtoDefault');
        }

        if ($bccEmails[0] === null) {
            $bccEmails = config('exceptions.emailExceptionBCCtoDefault');
        }

        if (! $fromSender) {
            $fromSender = config('exceptions.emailExceptionFromDefault');
        }

        if (! $subject) {
            $subject = config('exceptions.emailExceptionSubjectDefault');
        }

        return $this->from($fromSender)
                    ->to($emailsTo)
                    ->cc($ccEmails)
                    ->bcc($bccEmails)
                    ->subject($subject)
                    ->view(config('exceptions.emailExceptionView'))
                    ->with('content', $this->content)
                    ->with('css', $this->css);
    }
}

resources/views/emails/exception.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <style>{!! $css ?? '' !!}</style>
</head>
<body>
{!! $content ?? '' !!}
</body>
</html>

Please let me know if that works.

like image 141
Vipertecpro Avatar answered Oct 19 '22 07:10

Vipertecpro