Skip to content
Closed
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
7 changes: 1 addition & 6 deletions src/http/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use function array_diff_key;
use function array_flip;
use function htmlspecialchars;
use function http_response_code;
use function ini_set;

/**
Expand Down Expand Up @@ -117,23 +116,19 @@
{
$this->exception = $exception;

$this->unregister();

Check warning on line 119 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ public function handleException($exception): Response { $this->exception = $exception; - $this->unregister(); + if (php_sapi_name() !== 'cli') { $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; http_response_code($statusCode);

Check warning on line 119 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ public function handleException($exception): Response { $this->exception = $exception; - $this->unregister(); + if (php_sapi_name() !== 'cli') { $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; http_response_code($statusCode);

if (php_sapi_name() !== 'cli') {
$statusCode = 500;

if ($exception instanceof HttpException) {
$statusCode = $exception->statusCode;
}
$statusCode = $exception instanceof HttpException ? $exception->statusCode : 500;

Check warning on line 122 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "IncrementInteger": @@ @@ $this->exception = $exception; $this->unregister(); if (php_sapi_name() !== 'cli') { - $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; + $statusCode = $exception instanceof HttpException ? $exception->statusCode : 501; http_response_code($statusCode); } try {

Check warning on line 122 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "DecrementInteger": @@ @@ $this->exception = $exception; $this->unregister(); if (php_sapi_name() !== 'cli') { - $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; + $statusCode = $exception instanceof HttpException ? $exception->statusCode : 499; http_response_code($statusCode); } try {

Check warning on line 122 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "IncrementInteger": @@ @@ $this->exception = $exception; $this->unregister(); if (php_sapi_name() !== 'cli') { - $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; + $statusCode = $exception instanceof HttpException ? $exception->statusCode : 501; http_response_code($statusCode); } try {

Check warning on line 122 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "DecrementInteger": @@ @@ $this->exception = $exception; $this->unregister(); if (php_sapi_name() !== 'cli') { - $statusCode = $exception instanceof HttpException ? $exception->statusCode : 500; + $statusCode = $exception instanceof HttpException ? $exception->statusCode : 499; http_response_code($statusCode); } try {

http_response_code($statusCode);
}

try {
$this->logException($exception);

Check warning on line 128 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ http_response_code($statusCode); } try { - $this->logException($exception); + if ($this->discardExistingOutput) { $this->clearOutput(); }

Check warning on line 128 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ http_response_code($statusCode); } try { - $this->logException($exception); + if ($this->discardExistingOutput) { $this->clearOutput(); }

if ($this->discardExistingOutput) {
$this->clearOutput();

Check warning on line 131 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ try { $this->logException($exception); if ($this->discardExistingOutput) { - $this->clearOutput(); + } $response = $this->renderException($exception); } catch (Throwable $e) {

Check warning on line 131 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ try { $this->logException($exception); if ($this->discardExistingOutput) { - $this->clearOutput(); + } $response = $this->renderException($exception); } catch (Throwable $e) {
}

$response = $this->renderException($exception);
Expand Down Expand Up @@ -185,11 +180,11 @@
$response->data = 'An internal server error occurred.';

if (YII_DEBUG) {
$response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>';

Check warning on line 183 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $msg .= $previousException; $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { - $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; + $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); }

Check warning on line 183 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $msg .= $previousException; $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { - $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; + $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); }
$safeServerVars = array_diff_key(

Check warning on line 184 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayDiffKey": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = $_SERVER; $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;

Check warning on line 184 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayDiffKey": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = $_SERVER; $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;
$_SERVER,
array_flip(

Check warning on line 186 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayFlip": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = array_diff_key($_SERVER, ['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY']); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;

Check warning on line 186 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayFlip": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = array_diff_key($_SERVER, ['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY']); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;
[

Check warning on line 187 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = array_diff_key($_SERVER, array_flip(['AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;

Check warning on line 187 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ $response->data = 'An internal server error occurred.'; if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; - $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); + $safeServerVars = array_diff_key($_SERVER, array_flip(['AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); } return $response;
'API_KEY',
'AUTH_TOKEN',
'DB_PASSWORD',
Expand All @@ -197,7 +192,7 @@
],
),
);
$response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars);

Check warning on line 195 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Concat": @@ @@ if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); - $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); + $response->data .= VarDumper::export($safeServerVars) . "\n\$_SERVER = "; } return $response; }

Check warning on line 195 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Concat": @@ @@ if (YII_DEBUG) { $response->data = '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>'; $safeServerVars = array_diff_key($_SERVER, array_flip(['API_KEY', 'AUTH_TOKEN', 'DB_PASSWORD', 'SECRET_KEY'])); - $response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars); + $response->data .= VarDumper::export($safeServerVars) . "\n\$_SERVER = "; } return $response; }
}

return $response;
Expand Down
58 changes: 58 additions & 0 deletions tests/http/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,64 @@ public function testClearOutputCleansAllBuffersInNonTestEnvironment(): void
}
}

public function testHandleExceptionCallsHttpResponseCodeInNonCliSapi(): void
{
HTTPFunctions::set_sapi('apache2handler');

$errorHandler = new ErrorHandler();

$errorHandler->discardExistingOutput = false;

$exception = new Exception('Test exception for non-CLI SAPI');

$response = $errorHandler->handleException($exception);

self::assertSame(
'apache2handler',
HTTPFunctions::php_sapi_name(),
"Should return 'apache2handler' as the SAPI name when running in non-CLI environment.",
);
self::assertSame(
1,
HTTPFunctions::getHttpResponseCodeCalls(),
"Should call 'http_response_code()' exactly once in non-CLI SAPI; call count must be '1'.",
);
self::assertSame(
500,
$response->getStatusCode(),
"Should set status code to '500' for Exception in non-CLI SAPI.",
);
}

public function testHandleExceptionDoesNotCallHttpResponseCodeInCliSapi(): void
{
HTTPFunctions::set_sapi('cli');

$errorHandler = new ErrorHandler();

$errorHandler->discardExistingOutput = false;

$exception = new Exception('Test exception for CLI SAPI');

$response = $errorHandler->handleException($exception);

self::assertSame(
'cli',
HTTPFunctions::php_sapi_name(),
"Should return 'cli' as the SAPI name when running in CLI environment.",
);
self::assertSame(
0,
HTTPFunctions::getHttpResponseCodeCalls(),
"Should not call 'http_response_code()' in CLI SAPI; call count must remain '0'.",
);
self::assertSame(
500,
$response->getStatusCode(),
"Should set status code to '500' for Exception in CLI SAPI.",
);
}

public function testHandleExceptionResetsState(): void
{
$errorHandler = new ErrorHandler();
Expand Down
7 changes: 7 additions & 0 deletions tests/support/MockerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ public static function load(): void
$line,
),
],
[
'namespace' => 'yii2\extensions\psrbridge\http',
'name' => 'http_response_code',
'function' => static fn(int|null $response_code = null): int => HTTPFunctions::http_response_code(
$response_code,
),
],
[
'namespace' => 'yii2\extensions\psrbridge\http',
'name' => 'php_sapi_name',
Expand Down
13 changes: 13 additions & 0 deletions tests/support/stub/HTTPFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ final class HTTPFunctions
*/
private static int $headersSentLine = 0;

/**
* Tracks the number of times {@see \http_response_code()} was called.
*/
private static int $httpResponseCodeCalls = 0;

/**
* Tracks the HTTP response code.
*/
Expand Down Expand Up @@ -96,6 +101,11 @@ public static function getHeader(string $header): array
return self::$headers[strtolower($header)] ?? [];
}

public static function getHttpResponseCodeCalls(): int
{
return self::$httpResponseCodeCalls;
}

public static function hasHeader(string $header): bool
{
return array_key_exists(strtolower($header), self::$headers);
Expand Down Expand Up @@ -153,6 +163,8 @@ public static function headers_sent(mixed &$file = null, mixed &$line = null): b

public static function http_response_code(int|null $response_code = 0): int
{
self::$httpResponseCodeCalls++;

if ($response_code > 0) {
self::$responseCode = $response_code;
}
Expand All @@ -172,6 +184,7 @@ public static function reset(): void
self::$headersSent = false;
self::$headersSentFile = '';
self::$headersSentLine = 0;
self::$httpResponseCodeCalls = 0;
self::$responseCode = 200;
self::$sapi = 'cli';
self::$streamGetContentsShouldFail = false;
Expand Down
Loading