/**
* This method finally handles all PHP and user errors as well as the exceptions that
* have been thrown through the servlet processing.
*
* @param \AppserverIo\Appserver\ServletEngine\RequestHandler $requestHandler The request handler instance
* @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The actual request instance
* @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The actual request instance
*
* @return void
*/
public function handleErrors(RequestHandler $requestHandler, HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
{
// return immediately if we don't have any errors
if (sizeof($errors = $requestHandler->getErrors()) === 0) {
return;
}
// iterate over the errors to process each of them
foreach ($errors as $error) {
// prepare the error message
$message = $this->prepareMessage($error);
// 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);
}
}
}
// query whether or not, the error has an status code
if ($statusCode = $error->getStatusCode()) {
$servletResponse->setStatusCode($statusCode);
}
}
// 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('<br/>', $errors));
}
// query whether or not we've a client or an server error
if ($servletResponse->getStatusCode() > 399) {
try {
// create a local copy of the application
$application = $servletRequest->getContext();
// inject the application and servlet response
$servletRequest->injectResponse($servletResponse);
$servletRequest->injectContext($application);
// load the servlet context instance
$servletManager = $application->search(ServletContextInterface::IDENTIFIER);
// initialize the request URI for the error page to be rendered
$requestUri = null;
// iterate over the configured error pages to find a matching one
foreach ($servletManager->getErrorPages() as $errorCodePattern => $errorPage) {
// query whether or not we found an error page configured for the actual status code
if (fnmatch($errorCodePattern, $servletResponse->getStatusCode())) {
$requestUri = $errorPage;
break;
}
}
// query whether or not we've an found a configured error page
if ($requestUri == null) {
throw new ServletException(sprintf('Please configure an error page for status code %s', $servletResponse->getStatusCode()));
}
// initialize the request URI
$servletRequest->setRequestUri($requestUri);
// prepare the request with the new data
$servletRequest->prepare();
// reset the body stream to remove content, that has already been appended
$servletResponse->resetBodyStream();
// load the servlet path and session-ID
$servletPath = $servletRequest->getServletPath();
$sessionId = $servletRequest->getProposedSessionId();
// load and process the servlet
$servlet = $servletManager->lookup($servletPath, $sessionId);
$servlet->service($servletRequest, $servletResponse);
} catch (\Exception $e) {
// finally log the exception
$application->getInitialContext()->getSystemLogger()->critical($e->__toString());
// append the exception message to the body stream
$servletResponse->appendBodyStream($e->__toString());
}
}
}