generated from yiisoft/package-template
-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix #122: Do exit(1) after all shutdown functions, even postponed ones (
#123)
- Loading branch information
Showing
2 changed files
with
39 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,10 +41,17 @@ final class ErrorHandler | |
private bool $enabled = false; | ||
private bool $initialized = false; | ||
|
||
/** | ||
* @param LoggerInterface $logger Logger to write errors to. | ||
* @param ThrowableRendererInterface $defaultRenderer Default throwable renderer. | ||
* @param EventDispatcherInterface|null $eventDispatcher Event dispatcher for error events. | ||
* @param int $exitShutdownHandlerDepth Depth of the exit() shutdown handler to ensure it's executed last. | ||
*/ | ||
public function __construct( | ||
private LoggerInterface $logger, | ||
private ThrowableRendererInterface $defaultRenderer, | ||
private ?EventDispatcherInterface $eventDispatcher = null, | ||
private int $exitShutdownHandlerDepth = 2 | ||
Check warning on line 54 in src/ErrorHandler.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
Check warning on line 54 in src/ErrorHandler.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
|
||
) { | ||
} | ||
|
||
|
@@ -108,7 +115,7 @@ public function register(): void | |
|
||
$this->initializeOnce(); | ||
Check warning on line 116 in src/ErrorHandler.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
|
||
|
||
// Handles throwable, echo output and exit. | ||
// Handles throwable that isn't caught otherwise, echo output and exit. | ||
set_exception_handler(function (Throwable $t): void { | ||
Check warning on line 119 in src/ErrorHandler.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
|
||
if (!$this->enabled) { | ||
return; | ||
|
@@ -199,16 +206,41 @@ private function renderThrowableAndTerminate(Throwable $t): void | |
if (!empty($this->workingDirectory)) { | ||
chdir($this->workingDirectory); | ||
} | ||
// disable error capturing to avoid recursive errors while handling exceptions | ||
// Disable error capturing to avoid recursive errors while handling exceptions. | ||
$this->unregister(); | ||
// set preventive HTTP status code to 500 in case error handling somehow fails and headers are sent | ||
// Set preventive HTTP status code to 500 in case error handling somehow fails and headers are sent. | ||
http_response_code(Status::INTERNAL_SERVER_ERROR); | ||
|
||
echo $this->handle($t); | ||
$this->eventDispatcher?->dispatch(new ApplicationError($t)); | ||
|
||
register_shutdown_function(static function (): void { | ||
exit(1); | ||
}); | ||
$handler = $this->wrapShutdownHandler( | ||
static function (): void { | ||
exit(1); | ||
}, | ||
$this->exitShutdownHandlerDepth | ||
); | ||
|
||
register_shutdown_function($handler); | ||
} | ||
|
||
/** | ||
* Wraps shutdown handler into another shutdown handler to ensure it is called last after all other shutdown | ||
* functions, even those added to the end. | ||
* | ||
* @param callable $handler Shutdown handler to wrap. | ||
* @param int $depth Wrapping depth. | ||
* @return callable Wrapped handler. | ||
*/ | ||
private function wrapShutdownHandler(callable $handler, int $depth): callable | ||
{ | ||
$currentDepth = 0; | ||
while ($currentDepth < $depth) { | ||
$handler = static function() use ($handler): void { | ||
register_shutdown_function($handler); | ||
}; | ||
$currentDepth++; | ||
} | ||
return $handler; | ||
} | ||
} |