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); } }