From 494ab79d0f7886ffe171433ab6f75c14ba1c24c8 Mon Sep 17 00:00:00 2001 From: Sibghatullah Mujaddid Date: Thu, 11 Mar 2021 08:43:22 +0800 Subject: [PATCH] Accept callable class for reportable and renderable in exception handler --- .../Foundation/Exceptions/Handler.php | 8 ++++ .../FoundationExceptionsHandlerTest.php | 48 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index 38c29a3996c7..bedb1fca3be4 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -139,6 +139,10 @@ public function register() */ public function reportable(callable $reportUsing) { + if (! $reportUsing instanceof Closure) { + $reportUsing = Closure::fromCallable($reportUsing); + } + return tap(new ReportableHandler($reportUsing), function ($callback) { $this->reportCallbacks[] = $callback; }); @@ -152,6 +156,10 @@ public function reportable(callable $reportUsing) */ public function renderable(callable $renderUsing) { + if (! $renderUsing instanceof Closure) { + $renderUsing = Closure::fromCallable($renderUsing); + } + $this->renderCallbacks[] = $renderUsing; return $this; diff --git a/tests/Foundation/FoundationExceptionsHandlerTest.php b/tests/Foundation/FoundationExceptionsHandlerTest.php index 55b2d54982a5..755a01d9f31e 100644 --- a/tests/Foundation/FoundationExceptionsHandlerTest.php +++ b/tests/Foundation/FoundationExceptionsHandlerTest.php @@ -107,6 +107,20 @@ public function testHandlerCallsReportMethodWithDependencies() $this->handler->report(new ReportableException('Exception message')); } + public function testHandlerReportsExceptionUsingCallableClass() + { + $reporter = m::mock(ReportingService::class); + $reporter->shouldReceive('send')->withArgs(['Exception message'])->once(); + + $logger = m::mock(LoggerInterface::class); + $this->container->instance(LoggerInterface::class, $logger); + $logger->shouldNotReceive('error'); + + $this->handler->reportable(new CustomReporter($reporter)); + + $this->handler->report(new CustomException('Exception message')); + } + public function testReturnsJsonWithStackTraceWhenAjaxRequestAndDebugTrue() { $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(true); @@ -134,6 +148,15 @@ public function testReturnsCustomResponseFromRenderableCallback() $this->assertSame('{"response":"My custom exception response"}', $response); } + public function testReturnsCustomResponseFromCallableClass() + { + $this->handler->renderable(new CustomRenderer()); + + $response = $this->handler->render($this->request, new CustomException)->getContent(); + + $this->assertSame('{"response":"The CustomRenderer response"}', $response); + } + public function testReturnsCustomResponseWhenExceptionImplementsResponsable() { $response = $this->handler->render($this->request, new ResponsableException)->getContent(); @@ -302,6 +325,31 @@ public function context() } } +class CustomReporter +{ + private $service; + + public function __construct(ReportingService $service) + { + $this->service = $service; + } + + public function __invoke(CustomException $e) + { + $this->service->send($e->getMessage()); + + return false; + } +} + +class CustomRenderer +{ + public function __invoke(CustomException $e, $request) + { + return response()->json(['response' => 'The CustomRenderer response']); + } +} + interface ReportingService { public function send($message);