Reputation: 1403
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.
Upvotes: 7
Views: 2317
Reputation: 3284
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.
Upvotes: 3