From 8afcb79a8c39dd73e8f14a823eeeb4e97e23500e Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 26 Apr 2018 00:18:54 +0200 Subject: [PATCH] Fix and optimize error handling in console execution and request handler context --- CHANGELOG.md | 10 + build.default.properties | 2 +- .../Appserver/Console/ExecutionContext.php | 21 +- .../Appserver/Core/Utilities/Error.php | 118 ++++++++++ .../Core/Utilities/ErrorInterface.php | 62 ++++++ .../Appserver/Core/Utilities/ErrorUtil.php | 210 ++++++++++++++++++ .../ServletEngine/RequestHandler.php | 13 +- .../Appserver/ServletEngine/Utils/Error.php | 79 +------ .../ServletEngine/Utils/ErrorInterface.php | 30 +-- .../ServletEngine/Utils/ErrorUtil.php | 189 +++------------- 10 files changed, 459 insertions(+), 275 deletions(-) create mode 100644 src/AppserverIo/Appserver/Core/Utilities/Error.php create mode 100644 src/AppserverIo/Appserver/Core/Utilities/ErrorInterface.php create mode 100644 src/AppserverIo/Appserver/Core/Utilities/ErrorUtil.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d4c81b3c..602eca62f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +Version 1.1.5-beta6 + +## Bugfixes + +* Fix and optimize error handling in console execution and request handler context + +## Features + +* None + Version 1.1.5-beta5 ## Bugfixes diff --git a/build.default.properties b/build.default.properties index 660dbceac..69ebff17e 100644 --- a/build.default.properties +++ b/build.default.properties @@ -8,7 +8,7 @@ ;-------------------------------------------------------------------------------- ; ---- Module Release Settings -------------------------------------------------- -release.version = 1.1.5-beta5 +release.version = 1.1.5-beta6 release.name = Iron Knight ; ---- PHPCPD Settings ---------------------------------------------------------- diff --git a/src/AppserverIo/Appserver/Console/ExecutionContext.php b/src/AppserverIo/Appserver/Console/ExecutionContext.php index d81c94621..65b9b8b22 100644 --- a/src/AppserverIo/Appserver/Console/ExecutionContext.php +++ b/src/AppserverIo/Appserver/Console/ExecutionContext.php @@ -25,9 +25,9 @@ use AppserverIo\Psr\Servlet\SessionUtils; use AppserverIo\Psr\Application\ApplicationInterface; use AppserverIo\Appserver\Core\Environment; +use AppserverIo\Appserver\Core\Utilities\ErrorUtil; use AppserverIo\Appserver\Core\Utilities\LoggerUtils; use AppserverIo\Appserver\Core\Utilities\EnvironmentKeys; -use AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -158,7 +158,17 @@ public function write(ConnectionInterface $connection) */ public function errorHandler($errno, $errstr, $errfile, $errline) { - LoggerUtils::log(LogLevel::ERROR, sprintf('PHP %s: %s in %s on line %d', ErrorUtil::singleton()->mapErrorCode($errno), $errstr, $errfile, $errline)); + + // query whether or not we've to handle the passed error + if ($errno > error_reporting()) { + return true; + } + + // add the passed error information to the array with the errors + $error = ErrorUtil::singleton()->fromArray(array($errno, $errstr, $errfile, $errline)); + // log the error messge and return TRUE, to prevent execution of additinoal error handlers + LoggerUtils::log(LogLevel::ERROR, ErrorUtil::singleton()->prepareMessage($error)); + return true; } /** @@ -169,8 +179,13 @@ public function errorHandler($errno, $errstr, $errfile, $errline) */ public function shutdown() { + + // query whether or not, class has been shutdown by an unhandled error if ($lastError = error_get_last()) { - LoggerUtils::log(LogLevel::ERROR, $lastError); + // add the passed error information to the array with the errors + $error = ErrorUtil::singleton()->fromArray($lastError); + // log the error messge and return TRUE, to prevent execution of additinoal error handlers + LoggerUtils::log(LogLevel::ERROR, ErrorUtil::singleton()->prepareMessage($error)); } } } diff --git a/src/AppserverIo/Appserver/Core/Utilities/Error.php b/src/AppserverIo/Appserver/Core/Utilities/Error.php new file mode 100644 index 000000000..a9b1b1766 --- /dev/null +++ b/src/AppserverIo/Appserver/Core/Utilities/Error.php @@ -0,0 +1,118 @@ + + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ + +namespace AppserverIo\Appserver\Core\Utilities; + +/** + * Wrapper for an error triggered by PHP's default error handling. + * + * @author Tim Wagner + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ +class Error implements ErrorInterface +{ + + /** + * The error type. + * + * @var integer + */ + protected $type; + + /** + * The error message. + * + * @var integer + */ + protected $message; + + /** + * The name of the file where the error has been triggered. + * + * @var integer + */ + protected $file; + + /** + * The line in the file where the error has been triggered. + * + * @var integer + */ + protected $line; + + /** + * Initializes the error with the passed values. + * + * @param integer $type The error type + * @param string $message The error message + * @param string $file The name of the file where the error has been triggered + * @param integer $line The line in the file where the error has been triggered + */ + public function __construct($type, $message, $file, $line) + { + $this->type = $type; + $this->message = $message; + $this->file = $file; + $this->line = $line; + } + + /** + * Return's the error type. + * + * @return integer The error type + */ + public function getType() + { + return $this->type; + } + + /** + * Return's the error message. + * + * @return integer The error message + */ + public function getMessage() + { + return $this->message; + } + + /** + * Return's the name of the file where the error has been triggered. + * + * @return integer The filename + */ + public function getFile() + { + return $this->file; + } + + /** + * Return's the line in the file where the error has been triggered. + * + * @return integer The line number + */ + public function getLine() + { + return $this->line; + } +} diff --git a/src/AppserverIo/Appserver/Core/Utilities/ErrorInterface.php b/src/AppserverIo/Appserver/Core/Utilities/ErrorInterface.php new file mode 100644 index 000000000..4a0d06f64 --- /dev/null +++ b/src/AppserverIo/Appserver/Core/Utilities/ErrorInterface.php @@ -0,0 +1,62 @@ + + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ + +namespace AppserverIo\Appserver\Core\Utilities; + +/** + * Interface for wrapper implementations of errors triggered by PHP's default error handling. + * + * @author Tim Wagner + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ +interface ErrorInterface +{ + + /** + * Return's the error type. + * + * @return integer The error type + */ + public function getType(); + + /** + * Return's the error message. + * + * @return integer The error message + */ + public function getMessage(); + + /** + * Return's the name of the file where the error has been triggered. + * + * @return integer The filename + */ + public function getFile(); + + /** + * Return's the line in the file where the error has been triggered. + * + * @return integer The line number + */ + public function getLine(); +} diff --git a/src/AppserverIo/Appserver/Core/Utilities/ErrorUtil.php b/src/AppserverIo/Appserver/Core/Utilities/ErrorUtil.php new file mode 100644 index 000000000..7bb928d10 --- /dev/null +++ b/src/AppserverIo/Appserver/Core/Utilities/ErrorUtil.php @@ -0,0 +1,210 @@ + + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ + +namespace AppserverIo\Appserver\Core\Utilities; + +use Psr\Log\LogLevel; + +// define a custom user exception constant +define('E_EXCEPTION', 0); + +/** + * Utility class that providing functionality to handle PHP errors. + * + * @author Tim Wagner + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ +class ErrorUtil +{ + + /** + * The singleton instance. + * + * @var \AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil + */ + protected static $instance; + + /** + * Create's and return's the singleton instance. + * + * @return \AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil The singleton instance + */ + public static function singleton() + { + + // query whether or not the instance has already been created + if (ErrorUtil::$instance == null) { + ErrorUtil::$instance = new static(); + } + + // return the singleton instance + return ErrorUtil::$instance; + } + + /** + * Create's a new error instance with the values from the passed array. + * + * @param array $error The array containing the error information + * + * @return \AppserverIo\Appserver\Core\Utilities\ErrorInterface The error instance + */ + public function fromArray(array $error) + { + + // extract the array with the error information + list ($type, $message, $file, $line) = array_values($error); + + // initialize and return the error instance + return new Error($type, $message, $file, $line); + } + + /** + * Create's a new error instance from the passed exception. + * + * @param \Exception $e The exception to create the error instance from + * + * @return \AppserverIo\Appserver\Core\Utilities\ErrorInterface The error instance + */ + public function fromException(\Exception $e) + { + return new Error(E_EXCEPTION, $e->__toString(), $e->getFile(), $e->getLine(), $e->getCode()); + } + + /** + * Prepare's the error message for logging/rendering purposes. + * + * @param \AppserverIo\Appserver\Core\Utilities\ErrorInterface $error The error instance to create the message from + * + * @return string The error message + */ + public function prepareMessage(ErrorInterface $error) + { + return sprintf('PHP %s: %s in %s on line %d', $this->mapErrorCode($error), $error->getMessage(), $error->getFile(), $error->getLine()); + } + + /** + * Return's the log level for the passed error instance. + * + * @param \AppserverIo\Appserver\Core\Utilities\ErrorInterface $error The error instance to map the log level for + * + * @return string + */ + public function mapLogLevel(ErrorInterface $error) + { + + // initialize the log level, default is 'error' + $logLevel = LogLevel::ERROR; + + // query the error type + switch ($error->getType()) { + case E_WARNING: + case E_USER_WARNING: + case E_COMPILE_WARNING: + case E_RECOVERABLE_ERROR: + $logLevel = LogLevel::WARNING; + break; + + case E_NOTICE: + case E_USER_NOTICE: + case E_STRICT: + case E_DEPRECATED: + case E_USER_DEPRECATED: + $logLevel = LogLevel::NOTICE; + break; + + default: + break; + } + + // return the log level + return $logLevel; + } + + /** + * Return's the a human readable error representation for the passed error instance. + * + * @param \AppserverIo\Appserver\Core\Utilities\ErrorInterface $error The error instance + * + * @return string The human readable error representation + */ + public function mapErrorCode(ErrorInterface $error) + { + + // initialize the error representation + $wrapped = 'Unknown'; + + // query the error type + switch ($error->getType()) { + case E_EXCEPTION: + $wrapped = 'Exception'; + break; + + case E_PARSE: + case E_ERROR: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + $wrapped = 'Fatal Error'; + break; + + case E_WARNING: + case E_USER_WARNING: + case E_COMPILE_WARNING: + case E_RECOVERABLE_ERROR: + $wrapped = 'Warning'; + break; + + case E_NOTICE: + case E_USER_NOTICE: + $wrapped = 'Notice'; + break; + + case E_STRICT: + $wrapped = 'Strict'; + break; + + case E_DEPRECATED: + case E_USER_DEPRECATED: + $wrapped = 'Deprecated'; + break; + + default: + break; + } + + // return the human readable error representation + return $wrapped; + } + + /** + * Query whether or not the passed error type is fatal or not. + * + * @param integer $type The type to query for + * + * @return boolean TRUE if the passed type is a fatal error, else FALSE + */ + public function isFatal($type) + { + return in_array($type, array(E_EXCEPTION, E_PARSE, E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)); + } +} diff --git a/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php b/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php index 9c12157b2..38846bbc0 100644 --- a/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php +++ b/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php @@ -29,8 +29,8 @@ use AppserverIo\Psr\Servlet\SessionUtils; use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface; use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface; -use AppserverIo\Appserver\ServletEngine\Utils\Error; use AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil; +use AppserverIo\Appserver\Core\Utilities\ErrorInterface; /** * This is a request handler that is necessary to process each request of an @@ -237,12 +237,15 @@ public function errorHandler($errno, $errstr, $errfile, $errline) { // query whether or not we've to handle the passed error - if ($errno < error_reporting()) { + if ($errno > error_reporting()) { return true; } // add the passed error information to the array with the errors - $this->addError(new Error($errno, $errstr, $errfile, $errline)); + $error = ErrorUtil::singleton()->fromArray(array($errno, $errstr, $errfile, $errline)); + + // add the passed error information to the array with the errors + $this->addError($error); return true; } @@ -279,11 +282,11 @@ public function shutdown() /** * Append the passed error to the request handler's stack. * - * @param \AppserverIo\Appserver\ServletEngine\Utils\Error $error The error to append + * @param \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface $error The error to append * * @return void */ - public function addError(Error $error) + public function addError(ErrorInterface $error) { // create a local copy of the error stack $errors = $this->errors; diff --git a/src/AppserverIo/Appserver/ServletEngine/Utils/Error.php b/src/AppserverIo/Appserver/ServletEngine/Utils/Error.php index 65761122c..85686d903 100644 --- a/src/AppserverIo/Appserver/ServletEngine/Utils/Error.php +++ b/src/AppserverIo/Appserver/ServletEngine/Utils/Error.php @@ -29,37 +29,9 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io */ -class Error implements ErrorInterface +class Error extends \AppserverIo\Appserver\Core\Utilities\Error implements ErrorInterface { - /** - * The error type. - * - * @var integer - */ - protected $type; - - /** - * The error message. - * - * @var integer - */ - protected $message; - - /** - * The name of the file where the error has been triggered. - * - * @var integer - */ - protected $file; - - /** - * The line in the file where the error has been triggered. - * - * @var integer - */ - protected $line; - /** * The HTTP status code that has to be send back with the response. * @@ -76,53 +48,14 @@ class Error implements ErrorInterface * @param integer $line The line in the file where the error has been triggered * @param integer $statusCode The HTTP status code that has to be send back with the response */ - public function __construct($type, $message, $file, $line, $statusCode = 500) - { - $this->type = $type; - $this->message = $message; - $this->file = $file; - $this->line = $line; - $this->statusCode = $statusCode; - } - - /** - * Return's the error type. - * - * @return integer The error type - */ - public function getType() - { - return $this->type; - } - - /** - * Return's the error message. - * - * @return integer The error message - */ - public function getMessage() + public function __construct($type, $message, $file, $line, $statusCode = 0) { - return $this->message; - } - /** - * Return's the name of the file where the error has been triggered. - * - * @return integer The filename - */ - public function getFile() - { - return $this->file; - } + // invoke the parent method + parent::__construct($type, $message, $file, $line); - /** - * Return's the line in the file where the error has been triggered. - * - * @return integer The line number - */ - public function getLine() - { - return $this->line; + // initialize the status code + $this->statusCode = $statusCode; } /** diff --git a/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorInterface.php b/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorInterface.php index b530b28e3..8b87b0ff0 100644 --- a/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorInterface.php +++ b/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorInterface.php @@ -29,37 +29,9 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io */ -interface ErrorInterface +interface ErrorInterface extends \AppserverIo\Appserver\Core\Utilities\ErrorInterface { - /** - * Return's the error type. - * - * @return integer The error type - */ - public function getType(); - - /** - * Return's the error message. - * - * @return integer The error message - */ - public function getMessage(); - - /** - * Return's the name of the file where the error has been triggered. - * - * @return integer The filename - */ - public function getFile(); - - /** - * Return's the line in the file where the error has been triggered. - * - * @return integer The line number - */ - public function getLine(); - /** * Return's the HTTP status code that has to be send back with the response. * diff --git a/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorUtil.php b/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorUtil.php index 4b822c72d..c45220977 100644 --- a/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorUtil.php +++ b/src/AppserverIo/Appserver/ServletEngine/Utils/ErrorUtil.php @@ -20,19 +20,15 @@ namespace AppserverIo\Appserver\ServletEngine\Utils; -use Psr\Log\LogLevel; use AppserverIo\Lang\String; use AppserverIo\Lang\Boolean; -use AppserverIo\Logger\LoggerUtils; use AppserverIo\Psr\Servlet\ServletException; use AppserverIo\Psr\Servlet\ServletContextInterface; use AppserverIo\Psr\Servlet\Utils\RequestHandlerKeys; use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface; use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface; use AppserverIo\Appserver\ServletEngine\RequestHandler; - -// define a custom user exception constant -define('E_EXCEPTION', 0); +use AppserverIo\Appserver\Core\Utilities\LoggerUtils; /** * Utility class that providing functionality to handle PHP errors. @@ -43,31 +39,19 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io */ -class ErrorUtil +class ErrorUtil extends \AppserverIo\Appserver\Core\Utilities\ErrorUtil { /** - * The singleton instance. + * Create's a new error instance from the passed exception. * - * @var \AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil - */ - protected static $instance; - - /** - * Create's and return's the singleton instance. + * @param \Exception $e The exception to create the error instance from * - * @return \AppserverIo\Appserver\ServletEngine\Utils\ErrorUtil The singleton instance + * @return \AppserverIo\Appserver\Core\Utilities\ErrorInterface The error instance */ - public static function singleton() + public function fromException(\Exception $e) { - - // query whether or not the instance has already been created - if (ErrorUtil::$instance == null) { - ErrorUtil::$instance = new ErrorUtil(); - } - - // return the singleton instance - return ErrorUtil::$instance; + return new Error(E_EXCEPTION, $e->__toString(), $e->getFile(), $e->getLine(), $e->getCode() ? $e->getCode() : 500); } /** @@ -75,140 +59,16 @@ public static function singleton() * * @param array $error The array containing the error information * - * @return \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface The error instance + * @return \AppserverIo\Appserver\Core\Utilities\ErrorInterface The error instance */ public function fromArray(array $error) { - // initialize the variables - $type = 0; - $message = ''; - $file = ''; - $line = 0; - // extract the array with the error information - extract($error); + list ($type, $message, $file, $line) = array_values($error); // initialize and return the error instance - return new Error($type, $message, $file, $line); - } - - /** - * Create's a new error instance from the passed exception. - * - * @param \Exception $e The exception to create the error instance from - * - * @return \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface The error instance - */ - public function fromException(\Exception $e) - { - return new Error(E_EXCEPTION, $e->__toString(), $e->getFile(), $e->getLine(), $e->getCode() ? $e->getCode() : 500); - } - - /** - * Prepare's the error message for logging/rendering purposes. - * - * @param \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface $error The error instance to create the message from - * - * @return string The error message - */ - public function prepareMessage(ErrorInterface $error) - { - return sprintf('PHP %s: %s in %s on line %d', $this->mapErrorCode($error), $error->getMessage(), $error->getFile(), $error->getLine()); - } - - /** - * Return's the log level for the passed error instance. - * - * @param \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface $error The error instance to map the log level for - * - * @return string - */ - public function mapLogLevel(ErrorInterface $error) - { - - // initialize the log level, default is 'error' - $logLevel = LogLevel::ERROR; - - // query the error type - switch ($error->getType()) { - case E_WARNING: - case E_USER_WARNING: - case E_COMPILE_WARNING: - case E_RECOVERABLE_ERROR: - $logLevel = LogLevel::WARNING; - break; - - case E_NOTICE: - case E_USER_NOTICE: - case E_STRICT: - case E_DEPRECATED: - case E_USER_DEPRECATED: - $logLevel = LogLevel::NOTICE; - break; - - default: - break; - } - - // return the log level - return $logLevel; - } - - /** - * Return's the a human readable error representation for the passed error instance. - * - * @param \AppserverIo\Appserver\ServletEngine\Utils\ErrorInterface $error The error instance - * - * @return string The human readable error representation - */ - public function mapErrorCode(ErrorInterface $error) - { - - // initialize the error representation - $wrapped = 'Unknown'; - - // query the error type - switch ($error->getType()) { - case E_EXCEPTION: - $wrapped = 'Exception'; - break; - - case E_PARSE: - case E_ERROR: - case E_CORE_ERROR: - case E_COMPILE_ERROR: - case E_USER_ERROR: - $wrapped = 'Fatal Error'; - break; - - case E_WARNING: - case E_USER_WARNING: - case E_COMPILE_WARNING: - case E_RECOVERABLE_ERROR: - $wrapped = 'Warning'; - break; - - case E_NOTICE: - case E_USER_NOTICE: - $wrapped = 'Notice'; - break; - - case E_STRICT: - $wrapped = 'Strict'; - break; - - case E_DEPRECATED: - case E_USER_DEPRECATED: - $wrapped = 'Deprecated'; - break; - - default: - break; - } - - // return the human readable error representation - return $wrapped; + return new Error($type, $message, $file, $line, ErrorUtil::singleton()->isFatal($type) ? 500 : 0); } /** @@ -239,13 +99,14 @@ public function handleErrors( // query whether or not we have to log the error if (Boolean::valueOf(new String(ini_get('log_errors')))->booleanValue()) { - // create a local copy of the application - if ($application = $servletRequest->getContext()) { - // try to load the system logger from the application - if ($systemLogger = $application->getLogger(LoggerUtils::SYSTEM)) { - $systemLogger->log($this->mapLogLevel($error), $message); - } - } + LoggerUtils::log(ErrorUtil::mapLogLevel($error), $message); + } + + // we prepend the errors to the body stream if display_errors is on + if (Boolean::valueOf(new String(ini_get('display_errors')))->booleanValue()) { + $bodyContent = $servletResponse->getBodyContent(); + $servletResponse->resetBodyStream(); + $servletResponse->appendBodyStream(sprintf('%s
%s', $message, $bodyContent)); } // query whether or not, the error has an status code @@ -254,13 +115,6 @@ public function handleErrors( } } - // we add the error to the servlet request - $servletRequest->setAttribute(RequestHandlerKeys::ERROR_MESSAGES, $errors); - // we append the the errors to the body stream if display_errors is on - if (Boolean::valueOf(new String(ini_get('display_errors')))->booleanValue()) { - $servletResponse->appendBodyStream(implode('
', $errors)); - } - // query whether or not we've a client or an server error if ($servletResponse->getStatusCode() > 399) { try { @@ -302,6 +156,13 @@ public function handleErrors( $servletRequest->prepare(); // reset the body stream to remove content, that has already been appended $servletResponse->resetBodyStream(); + // we add the filtered errors (status code > 399) to the servlet request + $servletRequest->setAttribute( + RequestHandlerKeys::ERROR_MESSAGES, + array_filter($errors, function ($message) { + return $message->getStatusCode() > 399; + }) + ); // load the servlet path and session-ID $servletPath = $servletRequest->getServletPath(); $sessionId = $servletRequest->getProposedSessionId();