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
22 changes: 6 additions & 16 deletions src/http/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@

use Throwable;
use Yii;
use yii\base\{InvalidRouteException, UserException};
use yii\console\Exception;
use yii\base\{Exception, InvalidRouteException, UserException};
use yii\helpers\VarDumper;
use yii\web\HttpException;

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 +114,13 @@
{
$this->exception = $exception;

$this->unregister();

Check warning on line 117 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(); + try { $this->logException($exception); if ($this->discardExistingOutput) {

Check warning on line 117 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(); + try { $this->logException($exception); if ($this->discardExistingOutput) {

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

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

http_response_code($statusCode);
}

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

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

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

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

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

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

Check warning on line 123 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 123 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 @@ -175,7 +162,7 @@
*/
protected function handleFallbackExceptionMessage($exception, $previousException): Response
{
$response = $this->createErrorResponse();
$response = $this->createErrorResponse()->setStatusCode(500);

$msg = "An Error occurred while handling another error:\n";
$msg .= $exception;
Expand All @@ -185,11 +172,14 @@
$response->data = 'An internal server error occurred.';

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

$response->data = "<pre>{$message}</pre>";

$safeServerVars = array_diff_key(

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayDiffKey": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 179 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayDiffKey": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 181 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayFlip": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 181 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayFlip": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 182 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 182 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ if (YII_DEBUG) { $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 +187,7 @@
],
),
);
$response->data .= "\n\$_SERVER = " . VarDumper::export($safeServerVars);

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 .= "\n\$_SERVER = "; } return $response; }

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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); } return $response; }

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Concat": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 190 in src/http/ErrorHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 .= "\n\$_SERVER = "; } return $response; }

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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); } return $response; }

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Concat": @@ @@ $message = htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset); $response->data = "<pre>{$message}</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 Expand Up @@ -244,7 +234,7 @@
}

$file = $useErrorView ? $this->errorView : $this->exceptionView;
$response->data = $this->renderFile($file, ['exception' => $exception]);

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ ini_set('display_errors', '1'); } $file = $useErrorView ? $this->errorView : $this->exceptionView; - $response->data = $this->renderFile($file, ['exception' => $exception]); + $response->data = $this->renderFile($file, []); } } elseif ($response->format === Response::FORMAT_RAW) { $response->data = self::convertExceptionToString($exception);

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

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ ini_set('display_errors', '1'); } $file = $useErrorView ? $this->errorView : $this->exceptionView; - $response->data = $this->renderFile($file, ['exception' => $exception]); + $response->data = $this->renderFile($file, []); } } elseif ($response->format === Response::FORMAT_RAW) { $response->data = self::convertExceptionToString($exception);
}
} elseif ($response->format === Response::FORMAT_RAW) {
$response->data = self::convertExceptionToString($exception);
Expand Down
32 changes: 1 addition & 31 deletions tests/http/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace yii2\extensions\psrbridge\tests\http;

use PHPUnit\Framework\Attributes\{Group, RequiresPhpExtension, TestWith};
use PHPUnit\Framework\Attributes\{Group, RequiresPhpExtension};
use RuntimeException;
use Throwable;
use yii\base\{Exception, UserException};
Expand Down Expand Up @@ -148,36 +148,6 @@ public function testHandleExceptionWithGenericException(): void
);
}

#[TestWith(['apache2handler'])]
#[TestWith(['cli'])]
public function testHandleExceptionWithHttpException(string $sapi): void
{
HTTPFunctions::set_sapi($sapi);

$errorHandler = new ErrorHandler();

$errorHandler->discardExistingOutput = false;

$exception = new HttpException(404, 'Page not found');

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

self::assertSame(
404,
$response->getStatusCode(),
"Should preserve HTTP status code from 'HttpException'.",
);
self::assertNotEmpty(
$response->data,
'Should set response data for HTTP exception.',
);
self::assertSame(
$sapi,
HTTPFunctions::php_sapi_name(),
"Should return correct SAPI name '{$sapi}' for 'HttpException'.",
);
}

public function testHandleExceptionWithLongMessage(): void
{
$errorHandler = new ErrorHandler();
Expand Down
20 changes: 10 additions & 10 deletions tests/http/StatelessApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
use Psr\Http\Message\{ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface};
use stdClass;
use Yii;
use yii\base\{Exception, InvalidConfigException, Security};
use yii\base\Exception;
use yii\base\{InvalidConfigException, Security};
use yii\di\NotInstantiableException;
use yii\helpers\Json;
use yii\i18n\{Formatter, I18N};
Expand Down Expand Up @@ -741,8 +742,6 @@ public function testRenderExceptionSetsDisplayErrorsInDebugMode(): void

$initialBufferLevel = ob_get_level();

HTTPFunctions::set_sapi('apache2handler');

$_SERVER = [
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => 'site/trigger-exception',
Expand Down Expand Up @@ -795,8 +794,6 @@ public function testRenderExceptionWithErrorActionReturningResponseObject(): voi
{
@runkit_constant_redefine('YII_DEBUG', false);

HTTPFunctions::set_sapi('apache2handler');

$_SERVER = [
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => 'site/trigger-exception',
Expand Down Expand Up @@ -844,8 +841,6 @@ public function testRenderExceptionWithErrorActionReturningResponseObject(): voi
*/
public function testRenderExceptionWithRawFormat(): void
{
HTTPFunctions::set_sapi('apache2handler');

$_SERVER = [
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => 'site/trigger-exception',
Expand Down Expand Up @@ -889,7 +884,12 @@ public function testRenderExceptionWithRawFormat(): void
self::assertStringNotContainsString(
'<pre>',
$body,
'RAW format response should not contain HTML tags.',
"RAW format response should not contain HTML tag '<pre>'.",
);
self::assertStringNotContainsString(
'</pre>',
$body,
"RAW format response should not contain HTML tag '</pre>'.",
);
}

Expand Down Expand Up @@ -1086,9 +1086,9 @@ public function testReturnHtmlErrorResponseWhenErrorHandlerActionIsInvalid(): vo
$response = $app->handle($request);

self::assertSame(
200,
500,
$response->getStatusCode(),
"Response 'status code' should be '200' when 'ErrorHandler' is misconfigured and a nonexistent action is " .
"Response 'status code' should be '500' when 'ErrorHandler' is misconfigured and a nonexistent action is " .
"requested in 'StatelessApplication'.",
);
self::assertSame(
Expand Down
6 changes: 4 additions & 2 deletions tests/support/MockerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ public static function load(): void
],
[
'namespace' => 'yii2\extensions\psrbridge\http',
'name' => 'php_sapi_name',
'function' => static fn(): string => HTTPFunctions::php_sapi_name(),
'name' => 'http_response_code',
'function' => static fn(int|null $response_code = null): int => HTTPFunctions::http_response_code(
$response_code,
),
],
[
'namespace' => 'yii2\extensions\psrbridge\adapter',
Expand Down
16 changes: 0 additions & 16 deletions tests/support/stub/HTTPFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ final class HTTPFunctions
*/
private static int $responseCode = 200;

/**
* Tracks the current SAPI name for simulation.
*/
private static string $sapi = 'cli';

/**
* Controls whether stream_get_contents should fail.
*/
Expand Down Expand Up @@ -160,11 +155,6 @@ public static function http_response_code(int|null $response_code = 0): int
return self::$responseCode;
}

public static function php_sapi_name(): string
{
return self::$sapi;
}

public static function reset(): void
{
self::$flushedTimes = 0;
Expand All @@ -173,7 +163,6 @@ public static function reset(): void
self::$headersSentFile = '';
self::$headersSentLine = 0;
self::$responseCode = 200;
self::$sapi = 'cli';
self::$streamGetContentsShouldFail = false;
}

Expand All @@ -184,11 +173,6 @@ public static function set_headers_sent(bool $value = false, string $file = '',
self::$headersSentLine = $line;
}

public static function set_sapi(string $sapi): void
{
self::$sapi = $sapi;
}

public static function set_stream_get_contents_should_fail(bool $shouldFail = true): void
{
self::$streamGetContentsShouldFail = $shouldFail;
Expand Down
Loading