82 lines
2.3 KiB
PHP
82 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Contracts\ShouldNotifyAdmin;
|
|
use App\Notifications\SystemErrorNotification;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Throwable;
|
|
|
|
class AdminNotificationService
|
|
{
|
|
public function notifyError(Throwable $exception): void
|
|
{
|
|
if (! config('libra.notifications.system_notifications_enabled')) {
|
|
return;
|
|
}
|
|
|
|
$adminEmail = config('libra.notifications.admin_email');
|
|
|
|
if (empty($adminEmail)) {
|
|
return;
|
|
}
|
|
|
|
$errorKey = $this->getErrorKey($exception);
|
|
$throttleMinutes = config('libra.notifications.throttle_minutes', 15);
|
|
|
|
if (Cache::has($errorKey)) {
|
|
return;
|
|
}
|
|
|
|
Cache::put($errorKey, true, now()->addMinutes($throttleMinutes));
|
|
|
|
Notification::route('mail', $adminEmail)
|
|
->notifyNow(new SystemErrorNotification($exception));
|
|
}
|
|
|
|
protected function getErrorKey(Throwable $exception): string
|
|
{
|
|
return 'admin_notified:'.md5(get_class($exception).$exception->getMessage());
|
|
}
|
|
|
|
public function shouldNotifyAdmin(Throwable $exception): bool
|
|
{
|
|
if ($exception instanceof ShouldNotifyAdmin) {
|
|
return true;
|
|
}
|
|
|
|
$excludedTypes = [
|
|
\Illuminate\Validation\ValidationException::class,
|
|
\Illuminate\Auth\AuthenticationException::class,
|
|
\Illuminate\Auth\Access\AuthorizationException::class,
|
|
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
|
|
\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
|
|
\Illuminate\Session\TokenMismatchException::class,
|
|
];
|
|
|
|
foreach ($excludedTypes as $type) {
|
|
if ($exception instanceof $type) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ($exception instanceof \Illuminate\Database\QueryException) {
|
|
return $this->isCriticalDatabaseError($exception);
|
|
}
|
|
|
|
if ($exception instanceof \Symfony\Component\Mailer\Exception\TransportExceptionInterface) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected function isCriticalDatabaseError(\Illuminate\Database\QueryException $e): bool
|
|
{
|
|
$criticalCodes = ['2002', '1045', '1049'];
|
|
|
|
return in_array($e->getCode(), $criticalCodes);
|
|
}
|
|
}
|