From 19007aafa51e46272c56a651d375ab8d1ead2308 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 13:13:33 +0000 Subject: [PATCH] refactor(foundation): fold the Exception package into Foundation's v13-shaped Handler (task 4.5) illuminate/exception leaves the replace block; only illuminate/foundation remains for the flip. - Illuminate\Exception\Handler becomes Illuminate\Foundation\Exceptions\Handler, v13's name, and implements v13's ExceptionHandler contract (report/shouldReport/render/renderForConsole). Its constructor takes only the container, as v13's does, and debug mode is read from app.debug when an exception is displayed. - When no render callback answers, it renders the app's errors.{status} or errors.{N}xx view, as v13 does, and the plain page when there is none or it fails. The debug displayer (Whoops) still renders in debug mode and in the console. - An error raised while handling an error is reported through the same report callbacks before the fallback renders, as v13's HandleExceptions does. - The displayers move to Foundation\Exceptions\Displayers and the provider to Foundation\Providers. ExceptionHandlerAdapter goes: the queue worker's ExceptionHandler binding now resolves the handler itself. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo --- composer.json | 1 - .../Exception/ExceptionHandlerAdapter.php | 81 ----- src/Illuminate/Exception/composer.json | 33 -- src/Illuminate/Foundation/Application.php | 4 +- .../Foundation/Configuration/Exceptions.php | 4 +- .../ExceptionDisplayerInterface.php | 2 +- .../Exceptions/Displayers}/PlainDisplayer.php | 2 +- .../Displayers}/WhoopsDisplayer.php | 2 +- .../Displayers}/resources/plain.html | 0 .../Exceptions}/Handler.php | 125 +++---- .../Exceptions/ReportableHandler.php | 2 +- .../Providers}/ExceptionServiceProvider.php | 317 +++++++++--------- .../Queue/FailConsoleServiceProvider.php | 8 +- .../Exceptions}/HandlerTest.php | 139 +++++++- .../Exceptions}/PlainDisplayerTest.php | 2 +- .../Exceptions}/WhoopsDisplayerTest.php | 2 +- tests/Queue/QueueForkBridgeTest.php | 9 +- 17 files changed, 363 insertions(+), 370 deletions(-) delete mode 100644 src/Illuminate/Exception/ExceptionHandlerAdapter.php delete mode 100755 src/Illuminate/Exception/composer.json rename src/Illuminate/{Exception => Foundation/Exceptions/Displayers}/ExceptionDisplayerInterface.php (76%) rename src/Illuminate/{Exception => Foundation/Exceptions/Displayers}/PlainDisplayer.php (91%) rename src/Illuminate/{Exception => Foundation/Exceptions/Displayers}/WhoopsDisplayer.php (95%) rename src/Illuminate/{Exception => Foundation/Exceptions/Displayers}/resources/plain.html (100%) rename src/Illuminate/{Exception => Foundation/Exceptions}/Handler.php (79%) rename src/Illuminate/{Exception => Foundation/Providers}/ExceptionServiceProvider.php (79%) rename tests/{Exception => Foundation/Exceptions}/HandlerTest.php (70%) rename tests/{Exception => Foundation/Exceptions}/PlainDisplayerTest.php (93%) rename tests/{Exception => Foundation/Exceptions}/WhoopsDisplayerTest.php (95%) diff --git a/composer.json b/composer.json index 2c3ce2beb..8d4aa832a 100755 --- a/composer.json +++ b/composer.json @@ -68,7 +68,6 @@ "voku/portable-ascii": "2.0.3" }, "replace": { - "illuminate/exception": "self.version", "illuminate/foundation": "self.version" }, "require-dev": { diff --git a/src/Illuminate/Exception/ExceptionHandlerAdapter.php b/src/Illuminate/Exception/ExceptionHandlerAdapter.php deleted file mode 100644 index 2ba26b795..000000000 --- a/src/Illuminate/Exception/ExceptionHandlerAdapter.php +++ /dev/null @@ -1,81 +0,0 @@ -handler = $handler; - } - - /** - * Report an exception through the App::error() handlers. - * - * @param \Throwable $e - * @return void - */ - public function report(Throwable $e) - { - $this->handler->report($e); - } - - /** - * Determine if the exception should be reported. - * - * @param \Throwable $e - * @return bool - */ - public function shouldReport(Throwable $e) - { - return $this->handler->shouldReport($e); - } - - /** - * Render an exception into an HTTP response. - * - * @param \Illuminate\Http\Request $request - * @param \Throwable $e - * @return \Symfony\Component\HttpFoundation\Response - */ - public function render($request, Throwable $e) - { - return $this->handler->render($request, $e); - } - - /** - * Render an exception to the console. - * - * @param \Symfony\Component\Console\Output\OutputInterface $output - * @param \Throwable $e - * @return void - */ - public function renderForConsole($output, Throwable $e) - { - (new ConsoleApplication)->renderThrowable($e, $output); - } - -} diff --git a/src/Illuminate/Exception/composer.json b/src/Illuminate/Exception/composer.json deleted file mode 100755 index 3b1c18910..000000000 --- a/src/Illuminate/Exception/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "illuminate/exception", - "license": "MIT", - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "require": { - "php": ">=5.4.0", - "filp/whoops": "1.1.*", - "illuminate/support": "4.2.*", - "symfony/error-handler": "~6.4", - "symfony/http-foundation": "~6.4", - "symfony/http-kernel": "~6.4" - }, - "require-dev": { - "monolog/monolog": "~1.6" - }, - "autoload": { - "psr-0": { - "Illuminate\\Exception": "" - } - }, - "target-dir": "Illuminate/Exception", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "minimum-stability": "dev" -} diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 0297796e7..8207f2081 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -14,7 +14,7 @@ use Illuminate\Bus\BusServiceProvider; use Illuminate\Events\EventServiceProvider; use Illuminate\Routing\RoutingServiceProvider; -use Illuminate\Exception\ExceptionServiceProvider; +use Illuminate\Foundation\Providers\ExceptionServiceProvider; use Illuminate\Foundation\Configuration\ApplicationBuilder; use Illuminate\Config\FileEnvironmentVariablesLoader; use Symfony\Component\Console\Input\InputInterface; @@ -361,8 +361,6 @@ public function bootstrapWithStartScript() public function startExceptionHandling() { $this['exception']->register($this->environment()); - - $this['exception']->setDebug($this['config']['app.debug']); } /** diff --git a/src/Illuminate/Foundation/Configuration/Exceptions.php b/src/Illuminate/Foundation/Configuration/Exceptions.php index 2c7494176..ef89d0159 100644 --- a/src/Illuminate/Foundation/Configuration/Exceptions.php +++ b/src/Illuminate/Foundation/Configuration/Exceptions.php @@ -1,6 +1,6 @@ app = $app; - $this->debug = $debug; - $this->plainDisplayer = $plainDisplayer; - $this->debugDisplayer = $debugDisplayer; + $this->container = $container; } /** @@ -205,8 +183,13 @@ public function handleException($exception) try { $this->report($exception); - return $this->render($this->app['request'], $exception); + return $this->render($this->container['request'], $exception); } catch (Throwable $throwable) { + try { + $this->report($throwable); + } catch (Throwable) { + } + return $this->displayException($throwable); } } @@ -327,7 +310,7 @@ public function report(Throwable $e) { if ($this->shouldntReport($e)) return; - if (Reflector::isCallable($reportCallable = array($e, 'report')) && $this->app->call($reportCallable) !== false) + if (Reflector::isCallable($reportCallable = array($e, 'report')) && $this->container->call($reportCallable) !== false) { return; } @@ -337,7 +320,7 @@ public function report(Throwable $e) if ($reportCallback->handles($e) && $reportCallback($e) === false) return; } - $this->app->make('log')->error($e->getMessage(), array_merge($this->exceptionContext($e), $this->context(), array('exception' => $e))); + $this->container->make('log')->error($e->getMessage(), array_merge($this->exceptionContext($e), $this->context(), array('exception' => $e))); } /** @@ -386,7 +369,7 @@ protected function exceptionContext(Throwable $e) protected function context() { try { - return array_filter(array('userId' => $this->app['auth']->id())); + return array_filter(array('userId' => $this->container['auth']->id())); } catch (Throwable) { return array(); } @@ -421,7 +404,7 @@ public function render($request, Throwable $e) { $response = $renderCallback($e, $request); - if ( ! is_null($response)) return $this->app->prepareResponse($response); + if ( ! is_null($response)) return $this->container->prepareResponse($response); } } } @@ -466,8 +449,6 @@ protected function prepareException(Throwable $e) */ protected function displayException($exception) { - $displayer = $this->debug ? $this->debugDisplayer : $this->plainDisplayer; - if (! $exception instanceof \Exception) { if ($exception instanceof \ParseError) { $severity = \E_PARSE; @@ -486,28 +467,60 @@ protected function displayException($exception) ); } - return $displayer->display($exception); + if ($this->container->runningInConsole() || $this->inDebugMode()) + { + return $this->container['exception.debug']->display($exception); + } + + return $this->renderErrorView($exception); } /** - * Determine if we are running in the console. + * Render the app's error view for the exception's status, or the plain page. + * + * @param \Exception $exception + * @return \Symfony\Component\HttpFoundation\Response + */ + protected function renderErrorView($exception) + { + $status = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; + + $headers = $exception instanceof HttpExceptionInterface ? $exception->getHeaders() : array(); + + try { + foreach (array("errors.{$status}", 'errors.'.intdiv($status, 100).'xx') as $view) + { + if ($this->container['view']->exists($view)) + { + return new ViewResponse($this->container['view']->make($view, array('exception' => $exception)), $status, $headers); + } + } + } catch (Throwable) { + } + + return $this->container['exception.plain']->display($exception); + } + + /** + * Determine if the application is in debug mode. * * @return bool */ - public function runningInConsole() + protected function inDebugMode() { - return php_sapi_name() == 'cli'; + return $this->container->bound('config') && (bool) $this->container['config']->get('app.debug'); } /** - * Set the debug level for the handler. + * Render an exception to the console. * - * @param bool $debug + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param \Throwable $e * @return void */ - public function setDebug($debug) + public function renderForConsole($output, Throwable $e) { - $this->debug = $debug; + (new ConsoleApplication)->renderThrowable($e, $output); } } diff --git a/src/Illuminate/Foundation/Exceptions/ReportableHandler.php b/src/Illuminate/Foundation/Exceptions/ReportableHandler.php index ed0c6c9ea..ca2d22c2c 100644 --- a/src/Illuminate/Foundation/Exceptions/ReportableHandler.php +++ b/src/Illuminate/Foundation/Exceptions/ReportableHandler.php @@ -4,7 +4,7 @@ use Throwable; /** - * v13's reportable callback wrapper (task 4.5), used by Illuminate\Exception\Handler. + * v13's reportable callback wrapper (task 4.5), used by Foundation\Exceptions\Handler. */ class ReportableHandler { diff --git a/src/Illuminate/Exception/ExceptionServiceProvider.php b/src/Illuminate/Foundation/Providers/ExceptionServiceProvider.php similarity index 79% rename from src/Illuminate/Exception/ExceptionServiceProvider.php rename to src/Illuminate/Foundation/Providers/ExceptionServiceProvider.php index 0d65df231..63917b5b8 100755 --- a/src/Illuminate/Exception/ExceptionServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/ExceptionServiceProvider.php @@ -1,162 +1,155 @@ -registerDisplayers(); - - $this->registerHandler(); - } - - /** - * Register the exception displayers. - * - * @return void - */ - protected function registerDisplayers() - { - $this->registerPlainDisplayer(); - - $this->registerDebugDisplayer(); - } - - /** - * Register the exception handler instance. - * - * @return void - */ - protected function registerHandler() - { - $this->app->singleton('exception', function($app) - { - return new Handler($app, $app['exception.plain'], $app['exception.debug']); - }); - } - - /** - * Register the plain exception displayer. - * - * @return void - */ - protected function registerPlainDisplayer() - { - $this->app->singleton('exception.plain', function($app) - { - // If the application is running in a console environment, we will just always - // use the debug handler as there is no point in the console ever returning - // out HTML. This debug handler always returns JSON from the console env. - if ($app->runningInConsole()) - { - return $app['exception.debug']; - } - else - { - return new PlainDisplayer; - } - }); - } - - /** - * Register the Whoops exception displayer. - * - * @return void - */ - protected function registerDebugDisplayer() - { - $this->registerWhoops(); - - $this->app->singleton('exception.debug', function($app) - { - return new WhoopsDisplayer($app['whoops'], $app->runningInConsole()); - }); - } - - /** - * Register the Whoops error display service. - * - * @return void - */ - protected function registerWhoops() - { - $this->registerWhoopsHandler(); - - $this->app->singleton('whoops', function($app) - { - // We will instruct Whoops to not exit after it displays the exception as it - // will otherwise run out before we can do anything else. We just want to - // let the framework go ahead and finish a request on this end instead. - with($whoops = new Run)->allowQuit(false); - - $whoops->writeToOutput(false); - - return $whoops->pushHandler($app['whoops.handler']); - }); - } - - /** - * Register the Whoops handler for the request. - * - * @return void - */ - protected function registerWhoopsHandler() - { - if ($this->shouldReturnJson()) - { - $this->app->singleton('whoops.handler', function() - { - return new JsonResponseHandler; - }); - } - else - { - $this->registerPrettyWhoopsHandler(); - } - } - - /** - * Determine if the error provider should return JSON. - * - * @return bool - */ - protected function shouldReturnJson() - { - return $this->app->runningInConsole() || $this->requestWantsJson(); - } - - /** - * Determine if the request warrants a JSON response. - * - * @return bool - */ - protected function requestWantsJson() - { - return $this->app['request']->ajax() || $this->app['request']->wantsJson(); - } - - /** - * Register the "pretty" Whoops handler. - * - * @return void - */ - protected function registerPrettyWhoopsHandler() - { - $this->app->singleton('whoops.handler', function() - { - with($handler = new PrettyPageHandler)->setEditor('sublime'); - - return $handler; - }); - } - -} +registerDisplayers(); + + $this->registerHandler(); + } + + /** + * Register the exception displayers. + * + * @return void + */ + protected function registerDisplayers() + { + $this->registerPlainDisplayer(); + + $this->registerDebugDisplayer(); + } + + /** + * Register the exception handler instance. + * + * @return void + */ + protected function registerHandler() + { + $this->app->singleton('exception', function($app) + { + return new Handler($app); + }); + } + + /** + * Register the plain exception displayer. + * + * @return void + */ + protected function registerPlainDisplayer() + { + $this->app->singleton('exception.plain', function() + { + return new PlainDisplayer; + }); + } + + /** + * Register the Whoops exception displayer. + * + * @return void + */ + protected function registerDebugDisplayer() + { + $this->registerWhoops(); + + $this->app->singleton('exception.debug', function($app) + { + return new WhoopsDisplayer($app['whoops'], $app->runningInConsole()); + }); + } + + /** + * Register the Whoops error display service. + * + * @return void + */ + protected function registerWhoops() + { + $this->registerWhoopsHandler(); + + $this->app->singleton('whoops', function($app) + { + // We will instruct Whoops to not exit after it displays the exception as it + // will otherwise run out before we can do anything else. We just want to + // let the framework go ahead and finish a request on this end instead. + with($whoops = new Run)->allowQuit(false); + + $whoops->writeToOutput(false); + + return $whoops->pushHandler($app['whoops.handler']); + }); + } + + /** + * Register the Whoops handler for the request. + * + * @return void + */ + protected function registerWhoopsHandler() + { + if ($this->shouldReturnJson()) + { + $this->app->singleton('whoops.handler', function() + { + return new JsonResponseHandler; + }); + } + else + { + $this->registerPrettyWhoopsHandler(); + } + } + + /** + * Determine if the error provider should return JSON. + * + * @return bool + */ + protected function shouldReturnJson() + { + return $this->app->runningInConsole() || $this->requestWantsJson(); + } + + /** + * Determine if the request warrants a JSON response. + * + * @return bool + */ + protected function requestWantsJson() + { + return $this->app['request']->ajax() || $this->app['request']->wantsJson(); + } + + /** + * Register the "pretty" Whoops handler. + * + * @return void + */ + protected function registerPrettyWhoopsHandler() + { + $this->app->singleton('whoops.handler', function() + { + with($handler = new PrettyPageHandler)->setEditor('sublime'); + + return $handler; + }); + } + +} diff --git a/src/Illuminate/Queue/FailConsoleServiceProvider.php b/src/Illuminate/Queue/FailConsoleServiceProvider.php index 6cefed658..fcaa9ff5b 100644 --- a/src/Illuminate/Queue/FailConsoleServiceProvider.php +++ b/src/Illuminate/Queue/FailConsoleServiceProvider.php @@ -3,7 +3,6 @@ use Illuminate\Mail\Mailer; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Queue\Job; -use Illuminate\Exception\ExceptionHandlerAdapter; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Queue\Console\WorkCommand; use Illuminate\Queue\Console\RetryCommand; @@ -83,8 +82,9 @@ public function register() /** * ponytail: v13's Worker (built by QueueServiceProvider as 'queue.worker') reports - * failed jobs through Contracts\Debug\ExceptionHandler. Bind the fork adapter only - * when the worker command is built: bound globally, v13's routing Pipeline would + * failed jobs through Contracts\Debug\ExceptionHandler, which the fork Handler + * implements. Bind it only when the worker command is built: bound globally, v13's + * routing Pipeline would * start reporting+rendering HTTP exceptions itself instead of letting them reach the * fork Handler (and stop rethrowing them in tests). Remove at task 4.5. * @@ -97,7 +97,7 @@ protected function bindWorkerExceptionHandler($app) $app->singleton(ExceptionHandler::class, function($app) { - return new ExceptionHandlerAdapter($app['exception']); + return $app['exception']; }); } diff --git a/tests/Exception/HandlerTest.php b/tests/Foundation/Exceptions/HandlerTest.php similarity index 70% rename from tests/Exception/HandlerTest.php rename to tests/Foundation/Exceptions/HandlerTest.php index cdb960c20..89cfeead5 100644 --- a/tests/Exception/HandlerTest.php +++ b/tests/Foundation/Exceptions/HandlerTest.php @@ -1,11 +1,13 @@ getHandler(); $handler->renderable(fn (Throwable $e) => new Response('rendered', 500)); - $adapter = new ExceptionHandlerAdapter($handler); - $adapter->report(new DomainException('boom')); + self::assertInstanceOf(ExceptionHandler::class, $handler); + self::assertFalse($handler->shouldReport(new NotFoundHttpException('missing'))); + self::assertSame('rendered', $handler->render($this->app['request'], new DomainException('boom'))->getContent()); + } - self::assertSame(array(array('boom', DomainException::class)), $this->log->logged()); - self::assertFalse($adapter->shouldReport(new NotFoundHttpException('missing'))); - self::assertSame('rendered', $adapter->render($this->app['request'], new DomainException('boom'))->getContent()); + #[Test] + public function inProductionTheErrorViewForTheStatusRenders(): void + { + $handler = $this->getHandler(self::DEBUG_DISABLED, views: array('errors.500' => '500 page', 'errors.5xx' => '5xx page', 'errors.4xx' => '4xx page')); + + $server = $handler->handleException(new BindingResolutionException('not found')); + $unavailable = $handler->handleException(new HttpException(503, 'down', null, array('Retry-After' => '60'))); + $missing = $handler->handleException(new NotFoundHttpException('missing')); + + self::assertSame(array(500, '500 page'), array($server->getStatusCode(), $server->getContent())); + self::assertSame(array(503, '5xx page', '60'), array($unavailable->getStatusCode(), $unavailable->getContent(), $unavailable->headers->get('Retry-After'))); + self::assertSame(array(404, '4xx page'), array($missing->getStatusCode(), $missing->getContent())); + $this->plainDisplayer->display(Argument::cetera())->shouldNotBeCalled(); + } + + #[Test] + public function withoutAnErrorViewOrWhenItFailsThePlainDisplayerRenders(): void + { + $handler = $this->getHandler(self::DEBUG_DISABLED, views: array('errors.500' => new RuntimeException('view broken'))); + + $handler->handleException(new BindingResolutionException('not found')); + $handler->handleException(new NotFoundHttpException('missing')); + + $this->plainDisplayer->display(Argument::type(BindingResolutionException::class))->shouldBeCalledOnce(); + $this->plainDisplayer->display(Argument::type(NotFoundHttpException::class))->shouldBeCalledOnce(); + } + + #[Test] + public function anErrorWhileHandlingAnErrorIsReportedToo(): void + { + $handler = $this->getHandler(self::DEBUG_DISABLED); + $handler->renderable(function (BindingResolutionException $e) { + throw new DomainException('render failed'); + }); + + $handler->handleException(new BindingResolutionException('not found')); + + self::assertSame(array(array('not found', BindingResolutionException::class), array('render failed', DomainException::class)), $this->log->logged()); + } + + #[Test] + public function inTheConsoleTheDebugDisplayerRendersEvenInProduction(): void + { + $handler = $this->getHandler(self::DEBUG_DISABLED, console: true, views: array('errors.500' => '500 page')); + + self::assertSame('debug', $handler->handleException(new BindingResolutionException('not found'))->getContent()); + } + + #[Test] + public function debugModeIsReadFromTheConfigurationWhenDisplaying(): void + { + $handler = $this->getHandler(self::DEBUG_DISABLED); + $this->app['config']->set('app.debug', true); + + self::assertSame('debug', $handler->handleException(new BindingResolutionException('not found'))->getContent()); } - protected function getHandler(bool $debug = self::DEBUG_ENABLED): Handler + #[Test] + public function renderForConsoleWritesTheExceptionToTheOutput(): void { - $this->app = new Application; + $output = new BufferedOutput; + + $this->getHandler()->renderForConsole($output, new DomainException('console boom')); + + self::assertStringContainsString('console boom', $output->fetch()); + } + + protected function getHandler(bool $debug = self::DEBUG_ENABLED, bool $console = false, array $views = array()): Handler + { + $this->app = new class($console) extends Application { + public function __construct(private bool $console) + { + parent::__construct(); + } + + public function runningInConsole() + { + return $this->console; + } + }; $this->app->instance('request', Request::create('/hello')); $this->app->instance('log', $this->log = new HandlerTestLogger); + $this->app->instance('config', new Repository(array('app' => array('debug' => $debug)))); $this->plainDisplayer = $this->prophesize(ExceptionDisplayerInterface::class); $this->debugDisplayer = $this->prophesize(ExceptionDisplayerInterface::class); $this->plainDisplayer->display(Argument::cetera())->willReturn(new Response('plain', 500)); $this->debugDisplayer->display(Argument::cetera())->willReturn(new Response('debug', 500)); + $this->app->instance('exception.plain', $this->plainDisplayer->reveal()); + $this->app->instance('exception.debug', $this->debugDisplayer->reveal()); + + if ($views) $this->app->instance('view', new HandlerTestViews($views)); - return new Handler( - $this->app, - $this->plainDisplayer->reveal(), - $this->debugDisplayer->reveal(), - $debug - ); + return new Handler($this->app); + } +} + +class HandlerTestViews +{ + public function __construct(private array $views) + { + } + + public function exists($view) + { + return array_key_exists($view, $this->views); + } + + public function make($view, array $data = array()) + { + if ($this->views[$view] instanceof Throwable) throw $this->views[$view]; + + return new class($this->views[$view]) implements Renderable { + public function __construct(private string $content) + { + } + + public function render() + { + return $this->content; + } + }; } } diff --git a/tests/Exception/PlainDisplayerTest.php b/tests/Foundation/Exceptions/PlainDisplayerTest.php similarity index 93% rename from tests/Exception/PlainDisplayerTest.php rename to tests/Foundation/Exceptions/PlainDisplayerTest.php index f3343741b..6ca40bc32 100644 --- a/tests/Exception/PlainDisplayerTest.php +++ b/tests/Foundation/Exceptions/PlainDisplayerTest.php @@ -1,6 +1,6 @@ assertInstanceOf(WorkCommand::class, $app->make(WorkCommand::class)); $this->assertInstanceOf(Worker::class, $app->make('queue.worker')); - $adapter = $app->make(ExceptionHandler::class); - $adapter->report($exception); + $bound = $app->make(ExceptionHandler::class); + $bound->report($exception); - $this->assertInstanceOf(ExceptionHandlerAdapter::class, $adapter); + $this->assertSame($handler->reveal(), $bound); } public function testStringJobRunsItsFireMethod()