Learn How to Send an Email on Error Exceptions

Tutorials

April 13th, 2017

email-exception-leader.png

You’ve created a new Laravel app for your client and deployed it on the production server. Everything was working fine till a customer has a problem with the app because of some buggy code. He immediately leaves the app, and the same thing happens with multiple customers before you know about the bug. You fix the bug, and then everything is on track.

But what if you were notified immediately through e-mail (or another service) about the bug and you fix it ASAP. In Laravel, this can be done easily and in this post, we’re going to learn how.

In Laravel, all exceptions are handled by the App\Exceptions\Handler class. This class contains two methods: report and render. We’re only interested in report method; it is used to log exceptions or send them to an external service like Bugsnag or Sentry. By default, the report method simply passes the exception to the base class where the exception is logged. However, we can use it to send an email to developers about the exception.

1/**
2 * Report or log an exception.
3 *
4 * This is a great spot to send exceptions to Emails.
5 *
6 * @param \Exception $exception
7 * @return void
8 */
9public function report(Exception $exception)
10{
11 if ($this->shouldReport($exception)) {
12 $this->sendEmail($exception); // sends an email
13 }
14
15 return parent::report($exception);
16}
17
18/**
19 * Sends an email to the developer about the exception.
20 *
21 * @param \Exception $exception
22 * @return void
23 */
24public function sendEmail(Exception $exception)
25{
26 // sending email
27}

Here we are using shouldReport method to ignore exceptions which are listed in the $dontReport property of the exception handler.

Each type of email sent by the application is represented as a “mailable” class in Laravel. So, we need to create our mailable class using the make:mail command:

1$ php artisan make:mail ExceptionOccured

This will create a class ExceptionOccured in the app/Mail directory.

Merely sending the mail will not solve the problem. We need the full stack trace of the exception. And for that, we can use the Symfony’s Debug component.

1public function sendEmail(Exception $exception)
2{
3 try {
4 $e = FlattenException::create($exception);
5
6 $handler = new SymfonyExceptionHandler();
7
8 $html = $handler->getHtml($e);
9
10 Mail::to('developer@gmail.com')->send(new ExceptionOccured($html));
11 } catch (Exception $ex) {
12 dd($ex);
13 }
14}

Make sure you add the following code at the top of the file:

1use Mail;
2use Symfony\Component\Debug\Exception\FlattenException;
3use Symfony\Component\Debug\ExceptionHandler as SymfonyExceptionHandler;
4use App\Mail\ExceptionOccured;

Note—We have used the try block to avoid the infinite loop if the mail command fails.

Then, in your ExceptionOccured mailer class:

1<?php
2
3namespace App\Mail;
4
5use Illuminate\Bus\Queueable;
6use Illuminate\Mail\Mailable;
7use Illuminate\Queue\SerializesModels;
8use Illuminate\Contracts\Queue\ShouldQueue;
9
10class ExceptionOccured extends Mailable
11{
12 use Queueable, SerializesModels;
13
14 /**
15 * The body of the message.
16 *
17 * @var string
18 */
19 public $content;
20
21 /**
22 * Create a new message instance.
23 *
24 * @return void
25 */
26 public function __construct($content)
27 {
28 $this->content = $content;
29 }
30
31 /**
32 * Build the message.
33 *
34 * @return $this
35 */
36 public function build()
37 {
38 return $this->view('emails.exception')
39 ->with('content', $this->content);
40 }
41}

Add the following code in your emails.exception view file:

1{!! $content !!}

Now, whenever an exception is thrown in your application, you will receive an email with full stack trace. Cool!

I have created a Laravel package named squareboat/sneaker to do all this cumbersome work for you so you can concentrate on solving the bug.

Some of the features of the sneaker are:
– On/off emailing using .env file.
– Customizing the email body.
– Ignoring the exception generated by bots.

and more to come.

If you want the complete source code for this, I’m more than happy to share it and you can find the source code on Github

Filed in:

Amit Gupta

Love to code, and have fun when helping others. At the moment I'm a big fan of Laravel framework and I am now what some would refer to as an "evangelist". I love to help others learn more about Laravel and get them started on the road to success. I hang out a LOT in #laravel on Stackoverflow. I've been developing the web and mobile apps and what not for roughly 2 years now and I am learning more all the time.