Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
gilour
/
laravel
/
pulse
/
src
/
Recorders
:
Exceptions.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace Laravel\Pulse\Recorders; use Carbon\CarbonImmutable; use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Str; use Laravel\Pulse\Concerns\ConfiguresAfterResolving; use Laravel\Pulse\Events\ExceptionReported; use Laravel\Pulse\Pulse; use Throwable; /** * @internal */ class Exceptions { use Concerns\Ignores, Concerns\Sampling, ConfiguresAfterResolving; /** * Create a new recorder instance. */ public function __construct( protected Pulse $pulse, protected Repository $config, ) { // } /** * Register the recorder. */ public function register(callable $record, Application $app): void { $this->afterResolving($app, ExceptionHandler::class, fn (ExceptionHandler $handler) => $handler->reportable(fn (Throwable $e) => $record($e))); // @phpstan-ignore method.notFound $this->afterResolving($app, Dispatcher::class, fn (Dispatcher $events) => $events->listen(fn (ExceptionReported $event) => $record($event->exception))); } /** * Record the exception. */ public function record(Throwable $e): void { $timestamp = CarbonImmutable::now()->getTimestamp(); $this->pulse->lazy(function () use ($timestamp, $e) { $class = $this->resolveClass($e); if (! $this->shouldSample() || $this->shouldIgnore($class)) { return; } $location = $this->config->get('pulse.recorders.'.self::class.'.location') ? $this->resolveLocation($e) : null; $this->pulse->record( type: 'exception', key: json_encode([$class, $location], flags: JSON_THROW_ON_ERROR), timestamp: $timestamp, value: $timestamp, )->max()->count(); }); } /** * Resolve the exception class to record. * * @return class-string<Throwable> */ protected function resolveClass(Throwable $e): string { $previous = $e->getPrevious(); return match (true) { $e instanceof \Illuminate\View\ViewException && $previous, $e instanceof \Spatie\LaravelIgnition\Exceptions\ViewException && $previous => $previous::class, // @phpstan-ignore class.notFound default => $e::class, }; } /** * Resolve the exception location to record. */ protected function resolveLocation(Throwable $e): string { return match (true) { $e instanceof \Illuminate\View\ViewException => $this->resolveLocationFromViewException($e), $e instanceof \Spatie\LaravelIgnition\Exceptions\ViewException => $this->formatLocation($e->getFile(), $e->getLine()), // @phpstan-ignore class.notFound, class.notFound, class.notFound default => $this->resolveLocationFromTrace($e) }; } /* * Resolve the location of the original view file instead of the cached version. */ protected function resolveLocationFromViewException(Throwable $e): string { // Getting the line number in the view file is a bit tricky. preg_match('/\(View: (?P<path>.*?)\)/', $e->getMessage(), $matches); return $this->formatLocation($matches['path'], null); } /** * Resolve the location for the given exception. */ protected function resolveLocationFromTrace(Throwable $e): string { $firstNonVendorFrame = collect($e->getTrace()) ->firstWhere(fn (array $frame) => isset($frame['file']) && ! $this->isInternalFile($frame['file'])); if (! $this->isInternalFile($e->getFile()) || $firstNonVendorFrame === null) { return $this->formatLocation($e->getFile(), $e->getLine()); } return $this->formatLocation($firstNonVendorFrame['file'] ?? 'unknown', $firstNonVendorFrame['line'] ?? null); } /** * Determine whether a file should be considered internal. */ protected function isInternalFile(string $file): bool { return Str::startsWith($file, base_path('vendor')) || $file === base_path('artisan') || $file === public_path('index.php'); } /** * Format a file and line number and strip the base path. */ protected function formatLocation(string $file, ?int $line): string { return Str::replaceFirst(base_path(DIRECTORY_SEPARATOR), '', $file).(is_int($line) ? (':'.$line) : ''); } }