/** * 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()); } } }