diff --git a/src/Illuminate/Contracts/Debug/ExceptionHandler.php b/src/Illuminate/Contracts/Debug/ExceptionHandler.php index 504f163376bd..307800a934c4 100644 --- a/src/Illuminate/Contracts/Debug/ExceptionHandler.php +++ b/src/Illuminate/Contracts/Debug/ExceptionHandler.php @@ -14,11 +14,12 @@ interface ExceptionHandler * * @param \Throwable $e * @param array $context + * @param \Psr\Log\LogLevel::*|null $level * @return void * * @throws \Throwable */ - public function report(Throwable $e, array $context = []); + public function report(Throwable $e, array $context = [], ?string $level = null); /** * Determine if the exception should be reported. diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index 809f1ebf64b3..d67b295938d3 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -419,11 +419,12 @@ public function level($type, $level) * * @param \Throwable $e * @param array $context + * @param \Psr\Log\LogLevel::*|null $level * @return void * * @throws \Throwable */ - public function report(Throwable $e, array $context = []) + public function report(Throwable $e, array $context = [], ?string $level = null) { $e = $this->mapException($e); @@ -431,7 +432,7 @@ public function report(Throwable $e, array $context = []) return; } - $this->reportThrowable($e, $context); + $this->reportThrowable($e, $context, $level); } /** @@ -439,11 +440,12 @@ public function report(Throwable $e, array $context = []) * * @param \Throwable $e * @param array $context + * @param \Psr\Log\LogLevel::*|null $level * @return void * * @throws \Throwable */ - protected function reportThrowable(Throwable $e, array $context = []): void + protected function reportThrowable(Throwable $e, array $context = [], ?string $level = null): void { $this->reportedExceptionMap[$e] = true; @@ -466,7 +468,7 @@ protected function reportThrowable(Throwable $e, array $context = []): void throw $e; } - $level = $this->mapLogLevel($e); + $level ??= $this->mapLogLevel($e); $originallyReporting = $this->currentlyReporting; diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php index d53e61c3a84d..59727c2ebe99 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php @@ -101,11 +101,12 @@ public function __construct($originalHandler, $except = []) * * @param \Throwable $e * @param array $context + * @param \Psr\Log\LogLevel::*|null $level * @return void * * @throws \Exception */ - public function report(Throwable $e, array $context = []) + public function report(Throwable $e, array $context = [], ?string $level = null) { // } diff --git a/src/Illuminate/Foundation/helpers.php b/src/Illuminate/Foundation/helpers.php index 15bf9a0c55cb..ea4022d4a5f8 100644 --- a/src/Illuminate/Foundation/helpers.php +++ b/src/Illuminate/Foundation/helpers.php @@ -720,14 +720,15 @@ function redirect($to = null, $status = 302, $headers = [], $secure = null): Red * * @param \Throwable|string $exception * @param array $context + * @param \Psr\Log\LogLevel::*|null $level */ - function report($exception, array $context = []): void + function report($exception, array $context = [], ?string $level = null): void { if (is_string($exception)) { $exception = new Exception($exception); } - app(ExceptionHandler::class)->report($exception, $context); + app(ExceptionHandler::class)->report($exception, $context, $level); } } @@ -738,11 +739,12 @@ function report($exception, array $context = []): void * @param bool $boolean * @param \Throwable|string $exception * @param array $context + * @param \Psr\Log\LogLevel::*|null $level */ - function report_if($boolean, $exception, array $context = []): void + function report_if($boolean, $exception, array $context = [], ?string $level = null): void { if ($boolean) { - report($exception, $context); + report($exception, $context, $level); } } } @@ -754,11 +756,12 @@ function report_if($boolean, $exception, array $context = []): void * @param bool $boolean * @param \Throwable|string $exception * @param array $context + * @param \Psr\Log\LogLevel::*|null $level */ - function report_unless($boolean, $exception, array $context = []): void + function report_unless($boolean, $exception, array $context = [], ?string $level = null): void { if (! $boolean) { - report($exception, $context); + report($exception, $context, $level); } } } diff --git a/src/Illuminate/Support/Facades/Exceptions.php b/src/Illuminate/Support/Facades/Exceptions.php index f7c35ed6bf9c..ddec7e55505d 100644 --- a/src/Illuminate/Support/Facades/Exceptions.php +++ b/src/Illuminate/Support/Facades/Exceptions.php @@ -19,7 +19,7 @@ * @method static bool shouldStopRetries(\Throwable $e) * @method static \Illuminate\Foundation\Exceptions\Handler dontFlash(array|string $attributes) * @method static \Illuminate\Foundation\Exceptions\Handler level(string $type, string $level) - * @method static void report(\Throwable $e, array $context = []) + * @method static void report(\Throwable $e, array $context = [], ?string $level = null) * @method static bool isReporting(\Throwable $e) * @method static bool shouldReport(\Throwable $e) * @method static \Illuminate\Foundation\Exceptions\Handler throttleUsing(callable $throttleUsing) diff --git a/src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php b/src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php index 3292a159deab..b302e1763cb5 100644 --- a/src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php +++ b/src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php @@ -147,14 +147,15 @@ public function assertNothingReported() * * @param \Throwable $e * @param array $context + * @param \Psr\Log\LogLevel::*|null $level * @return void * * @throws \Throwable */ - public function report($e, array $context = []) + public function report($e, array $context = [], ?string $level = null) { if (! $this->isFakedException($e)) { - $this->handler->report($e, $context); + $this->handler->report($e, $context, $level); return; } diff --git a/tests/Foundation/FoundationExceptionsHandlerTest.php b/tests/Foundation/FoundationExceptionsHandlerTest.php index 4f16bdced2e4..5b487229aa74 100644 --- a/tests/Foundation/FoundationExceptionsHandlerTest.php +++ b/tests/Foundation/FoundationExceptionsHandlerTest.php @@ -168,6 +168,25 @@ public function testHandlerReportsExceptionWithCustomLogLevel() $this->handler->report(new OutOfRangeException('Custom message')); } + public function testHandlerReportsExceptionWithInlineLogLevel() + { + $logger = Mockery::mock(LoggerInterface::class); + $this->container->instance(LoggerInterface::class, $logger); + + $logger->expects('warning')->withArgs([ + 'Warning message', + Mockery::subset(['from' => 'user@example.com']), + ]); + + $this->handler->level(InvalidArgumentException::class, LogLevel::CRITICAL); + + $this->handler->report( + new InvalidArgumentException('Warning message'), + ['from' => 'user@example.com'], + LogLevel::WARNING, + ); + } + public function testHandlerIgnoresNotReportableExceptions() { $logger = Mockery::mock(LoggerInterface::class); diff --git a/tests/Integration/Foundation/FoundationHelpersTest.php b/tests/Integration/Foundation/FoundationHelpersTest.php index b64c43931f6f..f0231c9358ba 100644 --- a/tests/Integration/Foundation/FoundationHelpersTest.php +++ b/tests/Integration/Foundation/FoundationHelpersTest.php @@ -8,9 +8,24 @@ use Illuminate\Support\Str; use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; +use Psr\Log\LogLevel; class FoundationHelpersTest extends TestCase { + public function testReportHelpersForwardContextAndLevel() + { + $handler = new FakeHandler; + $this->app->instance(ExceptionHandler::class, $handler); + + report($first = new Exception('First'), ['id' => 1], LogLevel::WARNING); + report_if(true, $second = new Exception('Second'), ['id' => 2], LogLevel::NOTICE); + report_unless(false, $third = new Exception('Third'), ['id' => 3], LogLevel::INFO); + + $this->assertSame([$first, $second, $third], $handler->reported); + $this->assertSame([['id' => 1], ['id' => 2], ['id' => 3]], $handler->contexts); + $this->assertSame([LogLevel::WARNING, LogLevel::NOTICE, LogLevel::INFO], $handler->levels); + } + public function testRescue() { $this->assertSame( @@ -164,10 +179,14 @@ protected function makeManifest($directory = '') class FakeHandler { public $reported = []; + public $contexts = []; + public $levels = []; - public function report($exception) + public function report($exception, array $context = [], ?string $level = null) { $this->reported[] = $exception; + $this->contexts[] = $context; + $this->levels[] = $level; } public function render($exception) diff --git a/tests/Queue/QueueWorkerTest.php b/tests/Queue/QueueWorkerTest.php index 6daa67f4c48f..e748ebe06791 100755 --- a/tests/Queue/QueueWorkerTest.php +++ b/tests/Queue/QueueWorkerTest.php @@ -812,7 +812,7 @@ public function getConnectionName() class ShouldntRetryExceptionHandler implements ExceptionHandler { - public function report(\Throwable $e, array $context = []) + public function report(\Throwable $e, array $context = [], ?string $level = null) { // }