Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions src/Illuminate/Foundation/Bootstrap/HandleExceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class HandleExceptions
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
protected static $app;

/**
* Bootstrap the given application.
Expand All @@ -38,15 +38,15 @@ public function bootstrap(Application $app)
{
self::$reservedMemory = str_repeat('x', 10240);

$this->app = $app;
static::$app = $app;

error_reporting(-1);

set_error_handler([$this, 'handleError']);
set_error_handler($this->forwardsTo('handleError'));

set_exception_handler([$this, 'handleException']);
set_exception_handler($this->forwardsTo('handleException'));

register_shutdown_function([$this, 'handleShutdown']);
register_shutdown_function($this->forwardsTo('handleShutdown'));

if (! $app->environment('testing')) {
ini_set('display_errors', 'Off');
Expand Down Expand Up @@ -91,7 +91,7 @@ public function handleDeprecation($message, $file, $line)
}

try {
$logger = $this->app->make(LogManager::class);
$logger = static::$app->make(LogManager::class);
} catch (Exception $e) {
return;
}
Expand All @@ -112,7 +112,7 @@ public function handleDeprecation($message, $file, $line)
*/
protected function ensureDeprecationLoggerIsConfigured()
{
with($this->app['config'], function ($config) {
with(static::$app['config'], function ($config) {
if ($config->get('logging.channels.deprecations')) {
return;
}
Expand All @@ -132,7 +132,7 @@ protected function ensureDeprecationLoggerIsConfigured()
*/
protected function ensureNullLogDriverIsConfigured()
{
with($this->app['config'], function ($config) {
with(static::$app['config'], function ($config) {
if ($config->get('logging.channels.null')) {
return;
}
Expand Down Expand Up @@ -164,7 +164,7 @@ public function handleException(Throwable $e)
//
}

if ($this->app->runningInConsole()) {
if (static::$app->runningInConsole()) {
$this->renderForConsole($e);
} else {
$this->renderHttpResponse($e);
Expand All @@ -190,7 +190,7 @@ protected function renderForConsole(Throwable $e)
*/
protected function renderHttpResponse(Throwable $e)
{
$this->getExceptionHandler()->render($this->app['request'], $e)->send();
$this->getExceptionHandler()->render(static::$app['request'], $e)->send();
}

/**
Expand All @@ -217,6 +217,18 @@ protected function fatalErrorFromPhpError(array $error, $traceOffset = null)
return new FatalError($error['message'], 0, $error, $traceOffset);
}

/**
* Forward a method call to the given method if an application instance exists.
*
* @return callable
*/
protected function forwardsTo($method)
{
return fn (...$arguments) => static::$app
? $this->{$method}(...$arguments)
: false;
}

/**
* Determine if the error level is a deprecation.
*
Expand Down Expand Up @@ -246,6 +258,16 @@ protected function isFatal($type)
*/
protected function getExceptionHandler()
{
return $this->app->make(ExceptionHandler::class);
return static::$app->make(ExceptionHandler::class);
}

/**
* Clear the local application instance from memory.
*
* @return void
*/
public static function forgetApp()
{
static::$app = null;
}
}
3 changes: 2 additions & 1 deletion src/Illuminate/Foundation/Testing/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Carbon\CarbonImmutable;
use Illuminate\Console\Application as Artisan;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Bootstrap\HandleExceptions;
use Illuminate\Queue\Queue;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Facade;
Expand Down Expand Up @@ -200,8 +201,8 @@ protected function tearDown(): void
$this->beforeApplicationDestroyedCallbacks = [];

Artisan::forgetBootstrappers();

Queue::createPayloadUsing(null);
HandleExceptions::forgetApp();

if ($this->callbackException) {
throw $this->callbackException;
Expand Down
34 changes: 34 additions & 0 deletions tests/Foundation/Bootstrap/HandleExceptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use ErrorException;
use Illuminate\Config\Repository as Config;
use Illuminate\Container\Container;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\HandleExceptions;
use Illuminate\Log\LogManager;
use Mockery as m;
Expand Down Expand Up @@ -208,6 +209,39 @@ public function testIgnoreDeprecationIfLoggerUnresolvable()
17
);
}

public function testForgetApp()
{
$appResolver = fn () => with(new ReflectionClass($this->handleExceptions), function ($reflection) {
$property = tap($reflection->getProperty('app'))->setAccessible(true);

return $property->getValue($this->handleExceptions);
});

$this->assertNotNull($appResolver());

handleExceptions::forgetApp();

$this->assertNull($appResolver());
}

public function testHandlerForgetsPreviousApp()
{
$appResolver = fn () => with(new ReflectionClass($this->handleExceptions), function ($reflection) {
$property = tap($reflection->getProperty('app'))->setAccessible(true);

return $property->getValue($this->handleExceptions);
});

$this->assertSame($this->container, $appResolver());

$this->handleExceptions->bootstrap($newApp = tap(m::mock(Application::class), function ($app) {
$app->shouldReceive('environment')->once()->andReturn(true);
}));

$this->assertNotSame($this->container, $appResolver());
$this->assertSame($newApp, $appResolver());
}
}

class CustomNullHandler extends NullHandler
Expand Down