mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
php > ini_set('display_errors', '1'); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', 1); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', true); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', 'true'); php > var_dump(ini_get('display_errors')); string(4) "true"
157 lines
4.6 KiB
PHP
157 lines
4.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This file is part of CodeIgniter 4 framework.
|
|
*
|
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace CodeIgniter\Debug;
|
|
|
|
use CodeIgniter\API\ResponseTrait;
|
|
use CodeIgniter\Exceptions\PageNotFoundException;
|
|
use CodeIgniter\HTTP\Exceptions\HTTPException;
|
|
use CodeIgniter\HTTP\IncomingRequest;
|
|
use CodeIgniter\HTTP\RequestInterface;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
use Config\Paths;
|
|
use Throwable;
|
|
|
|
/**
|
|
* @see \CodeIgniter\Debug\ExceptionHandlerTest
|
|
*/
|
|
final class ExceptionHandler extends BaseExceptionHandler implements ExceptionHandlerInterface
|
|
{
|
|
use ResponseTrait;
|
|
|
|
/**
|
|
* ResponseTrait needs this.
|
|
*/
|
|
private ?RequestInterface $request = null;
|
|
|
|
/**
|
|
* ResponseTrait needs this.
|
|
*/
|
|
private ?ResponseInterface $response = null;
|
|
|
|
/**
|
|
* Determines the correct way to display the error.
|
|
*/
|
|
public function handle(
|
|
Throwable $exception,
|
|
RequestInterface $request,
|
|
ResponseInterface $response,
|
|
int $statusCode,
|
|
int $exitCode
|
|
): void {
|
|
// ResponseTrait needs these properties.
|
|
$this->request = $request;
|
|
$this->response = $response;
|
|
|
|
if ($request instanceof IncomingRequest) {
|
|
try {
|
|
$response->setStatusCode($statusCode);
|
|
} catch (HTTPException $e) {
|
|
// Workaround for invalid HTTP status code.
|
|
$statusCode = 500;
|
|
$response->setStatusCode($statusCode);
|
|
}
|
|
|
|
if (! headers_sent()) {
|
|
header(
|
|
sprintf(
|
|
'HTTP/%s %s %s',
|
|
$request->getProtocolVersion(),
|
|
$response->getStatusCode(),
|
|
$response->getReasonPhrase()
|
|
),
|
|
true,
|
|
$statusCode
|
|
);
|
|
}
|
|
|
|
if (strpos($request->getHeaderLine('accept'), 'text/html') === false) {
|
|
$data = (ENVIRONMENT === 'development' || ENVIRONMENT === 'testing')
|
|
? $this->collectVars($exception, $statusCode)
|
|
: '';
|
|
|
|
$this->respond($data, $statusCode)->send();
|
|
|
|
if (ENVIRONMENT !== 'testing') {
|
|
// @codeCoverageIgnoreStart
|
|
exit($exitCode);
|
|
// @codeCoverageIgnoreEnd
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Determine possible directories of error views
|
|
$addPath = ($request instanceof IncomingRequest ? 'html' : 'cli') . DIRECTORY_SEPARATOR;
|
|
$path = $this->viewPath . $addPath;
|
|
$altPath = rtrim((new Paths())->viewDirectory, '\\/ ')
|
|
. DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . $addPath;
|
|
|
|
// Determine the views
|
|
$view = $this->determineView($exception, $path);
|
|
$altView = $this->determineView($exception, $altPath);
|
|
|
|
// Check if the view exists
|
|
$viewFile = null;
|
|
if (is_file($path . $view)) {
|
|
$viewFile = $path . $view;
|
|
} elseif (is_file($altPath . $altView)) {
|
|
$viewFile = $altPath . $altView;
|
|
}
|
|
|
|
// Displays the HTML or CLI error code.
|
|
$this->render($exception, $statusCode, $viewFile);
|
|
|
|
if (ENVIRONMENT !== 'testing') {
|
|
// @codeCoverageIgnoreStart
|
|
exit($exitCode);
|
|
// @codeCoverageIgnoreEnd
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines the view to display based on the exception thrown,
|
|
* whether an HTTP or CLI request, etc.
|
|
*
|
|
* @return string The filename of the view file to use
|
|
*/
|
|
protected function determineView(Throwable $exception, string $templatePath): string
|
|
{
|
|
// Production environments should have a custom exception file.
|
|
$view = 'production.php';
|
|
|
|
if (
|
|
in_array(
|
|
strtolower(ini_get('display_errors')),
|
|
['1', 'true', 'on', 'yes'],
|
|
true
|
|
)
|
|
) {
|
|
$view = 'error_exception.php';
|
|
}
|
|
|
|
// 404 Errors
|
|
if ($exception instanceof PageNotFoundException) {
|
|
return 'error_404.php';
|
|
}
|
|
|
|
$templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR;
|
|
|
|
// Allow for custom views based upon the status code
|
|
if (is_file($templatePath . 'error_' . $exception->getCode() . '.php')) {
|
|
return 'error_' . $exception->getCode() . '.php';
|
|
}
|
|
|
|
return $view;
|
|
}
|
|
}
|