Skip to content

Commit

Permalink
Exception Mailer
Browse files Browse the repository at this point in the history
  • Loading branch information
cholladay0816 committed Sep 14, 2023
1 parent 4500aff commit 80380ed
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 3 deletions.
27 changes: 26 additions & 1 deletion app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace App\Exceptions;

use App\Mail\ExceptionOccured;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Log;
use Throwable;

class Handler extends ExceptionHandler
Expand Down Expand Up @@ -34,7 +36,30 @@ class Handler extends ExceptionHandler
public function register()
{
$this->reportable(function (Throwable $e) {
//
$this->sendEmail($e);
});
}

/**
* Sends an email upon exception.
*
* @param \Throwable $exception
*
* @return void
*/
public function sendEmail(Throwable $exception)
{
try {
$content['message'] = $exception->getMessage();
$content['file'] = $exception->getFile();
$content['line'] = $exception->getLine();
$content['trace'] = $exception->getTrace();
$content['url'] = request()->url();
$content['body'] = request()->all();
$content['ip'] = request()->ip();
\Illuminate\Support\Facades\Mail::send(new ExceptionOccured($content));
} catch (Throwable $exception) {
Log::error($exception);
}
}
}
2 changes: 1 addition & 1 deletion app/Http/Livewire/FindAGig.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function render()
public function updatedSearch()
{
$this->commissions = CommissionPreset::where('title', 'LIKE', "%{$this->search}%")
->orderBy('rating', 'DESC')
// ->orderBy('rating', 'DESC')
->orderBy('price', 'ASC')
->paginate($this->count);
}
Expand Down
66 changes: 66 additions & 0 deletions app/Mail/ExceptionOccured.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Mail;

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

class ExceptionOccured extends Mailable
{
use Queueable, SerializesModels;

private $content;

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

/**
* 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);
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"fruitcake/laravel-cors": "^2.0",
"google/recaptcha": "^1.2",
"guzzlehttp/guzzle": "^7.0.1",
"jeremykenedy/laravel-exception-notifier": "^3.1",
"laravel/cashier": "^12.6",
"laravel/framework": "^9.0",
"laravel/jetstream": "^2.3.0, !=2.3.1",
Expand Down
75 changes: 74 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 88 additions & 0 deletions config/exceptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

return [

/*
|--------------------------------------------------------------------------
| Exception Email Enabled
|--------------------------------------------------------------------------
|
| Enable/Disable exception email notifications
|
*/

'emailExceptionEnabled' => env('EMAIL_EXCEPTION_ENABLED'),
'emailExceptionEnabledDefault' => true,

/*
|--------------------------------------------------------------------------
| Exception Email From
|--------------------------------------------------------------------------
|
| This is the email your exception will be from.
|
*/

'emailExceptionFrom' => env('EMAIL_EXCEPTION_FROM'),
'emailExceptionFromDefault' => '[email protected]',

/*
|--------------------------------------------------------------------------
| Exception Email To
|--------------------------------------------------------------------------
|
| This is the email(s) the exceptions will be emailed to.
|
*/

'emailExceptionsTo' => env('EMAIL_EXCEPTION_TO'),
'emailExceptionsToDefault' => env('MAIL_SUPPORT'),

/*
|--------------------------------------------------------------------------
| Exception Email CC
|--------------------------------------------------------------------------
|
| This is the email(s) the exceptions will be CC emailed to.
|
*/

'emailExceptionCCto' => env('EMAIL_EXCEPTION_CC'),
'emailExceptionCCtoDefault' => [],

/*
|--------------------------------------------------------------------------
| Exception Email BCC
|--------------------------------------------------------------------------
|
| This is the email(s) the exceptions will be BCC emailed to.
|
*/

'emailExceptionBCCto' => env('EMAIL_EXCEPTION_BCC'),
'emailExceptionBCCtoDefault' => [],

/*
|--------------------------------------------------------------------------
| Exception Email Subject
|--------------------------------------------------------------------------
|
| This is the subject of the exception email
|
*/

'emailExceptionSubject' => env('EMAIL_EXCEPTION_SUBJECT'),
'emailExceptionSubjectDefault' => 'Error on '.config('app.env'),

/*
|--------------------------------------------------------------------------
| Exception Email View
|--------------------------------------------------------------------------
|
| This is the view that will be used for the email.
|
*/

'emailExceptionView' => 'emails.exception',

];
81 changes: 81 additions & 0 deletions resources/views/emails/exception.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow" />
<style>
body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }
a { cursor: pointer; text-decoration: none; }
a:hover { text-decoration: underline; }
abbr[title] { border-bottom: none; cursor: help; text-decoration: none; }
code, pre { font: 13px/1.5 Consolas, Monaco, Menlo, "Ubuntu Mono", "Liberation Mono", monospace; }
table, tr, th, td { background: #FFF; border-collapse: collapse; vertical-align: top; }
table { background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2); margin: 1em 0; width: 100%; }
table th, table td { border: solid #E0E0E0; border-width: 1px 0; padding: 8px 10px; }
table th { background-color: #E0E0E0; font-weight: bold; text-align: left; }
.hidden-xs-down { display: none; }
.block { display: block; }
.break-long-words { -ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; }
.text-muted { color: #999; }
.container { max-width: 1024px; margin: 0 auto; padding: 0 15px; }
.container::after { content: ""; display: table; clear: both; }
.exception-summary { background: #B0413E; border-bottom: 2px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, .3); flex: 0 0 auto; margin-bottom: 30px; }
.exception-message-wrapper { display: flex; align-items: center; min-height: 70px; }
.exception-message { flex-grow: 1; padding: 30px 0; }
.exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; }
.exception-message.long { font-size: 18px; }
.exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; }
.exception-message a:hover { border-bottom-color: #ffffff; }
.exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
.trace + .trace { margin-top: 30px; }
.trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }
.trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }
.trace-file-path, .trace-file-path a { color: #222; margin-top: 3px; font-size: 13px; }
.trace-class { color: #B0413E; }
.trace-type { padding: 0 2px; }
.trace-method { color: #B0413E; font-weight: bold; }
.trace-arguments { color: #777; font-weight: normal; padding-left: 2px; }
@media (min-width: 575px) {
.hidden-xs-down { display: initial; }
}</style>
</head>
<body>
<div class="exception-summary">
<div class="container">
<div class="exception-message-wrapper">
<h1 class="break-long-words exception-message">{{ $content['message'] ?? '' }}</h1>
<div class="exception-illustration hidden-xs-down"></div>
</div>
</div>
</div>
<div class="container">
<div class="trace trace-as-html">
<table class="trace-details">
<thead class="trace-head"><tr><th>
<h3 class="trace-class">
<span class="text-muted">(1/1)</span>
<span class="exception_title"><span title="ErrorException">ErrorException</span></span>
</h3>
<p class="break-long-words trace-message">{{ $content['message'] ?? '' }}</p>
<p class="">URL: {{ $content['url'] ?? '' }}</p>
<p class="">IP: {{ $content['ip'] ?? '' }}</p>
</th></tr></thead>
<tbody>
<tr>
<td>
<span class="block trace-file-path">in <span title="{{ $content['file'] ?? '' }}"><strong>{{ $content['file'] ?? '' }}</strong> line {{ $content['line'] ?? '' }}</span></span>
</td>
</tr>
@foreach(($content['trace'] ?? []) as $value)
<tr>
<td>
at <span class="trace-class"><span title="{{ $value['class'] ?? '' }}">{{ basename($value['class'] ?? '') }}</span></span><span class="trace-type">-></span><span class="trace-method">{{ $value['function'] ?? '' }}</span>(<span class="trace-arguments"></span>)<span class="block trace-file-path">in <span title=""><strong>{{ $value['file'] ?? '' }}</strong> line {{ $value['line'] ?? '' }}</span></span>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</body>
</html>

0 comments on commit 80380ed

Please sign in to comment.