Sending Laravel exceptions to your email
19th of July, 2018 - Mark Halcroft
In this quick tutorial, I'd like to show you a practical example of how I send Laravel "Whoops" exceptions to my email.
Creating the Mailer
First, let's create the Mailer class that will handle sending the exception to our email. In your terminal, navigate to your project and run the following artisan
command:
$ php artisan make:mail Exception
Open your newly created Mailer class from app/Mail/Exception.php
and use the following:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class Exception extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*
* @param $data
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('emails.exception')
->subject('Exception Logged!')
->from('exceptions@domain.com')
->to('youremail@domain.com')
->with([
'data' => $this->data,
]);
}
}
Updating the Exception Handler
Now that we have our Mailer class, we can go and make some changes the default Exception Handler class at app/Exceptions/Handler.php
.
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\Debug\ExceptionHandler as SymfonyExceptionHandler;
use App\Mail\Exception as ExceptionMail;
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
* @throws Exception
*/
public function report(Exception $exception)
{
if ($this->shouldReport($exception)) {
$this->sendExceptionEmail($exception);
}
parent::report($exception);
}
/**
* Parse the exception and send email
*
* @param Exception $exception
*/
public function sendExceptionEmail(Exception $exception)
{
try {
$e = FlattenException::create($exception);
$handler = new SymfonyExceptionHandler();
$html = $handler->getHtml($e);
Mail::queue(new ExceptionMail($html));
} catch (Exception $e) {
//
}
}
/**
* 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)
{
/**
* Had to put this in because it was throwing an exception if the user wasn't unauthenticated
*/
if ( ! $this->shouldReport($exception)) {
return parent::render($request, $exception);
}
if(config('app.debug')) {
return parent::render($request, $exception);
}
return response()->view('errors.custom', [], 500);
}
}
Create the view
This is the easy part. Simply create a new blade view file at views/emails/exception.blade.php
and add the following:
{!! $data !!}
That's it!
Hi
My name is Mark Halcroft. I am a web developer and founder of Brainbook where we make websites and web apps for - but not limited to - the A/V industry. We specialise in Laravel and PHP and are based in Melbourne, Australia.