/** * For internal use only. */ public function _runPieCrustRequest(\StupidHttp_HandlerContext $context) { $startTime = microtime(true); // Things like the plugin loader will add paths to the PHP include path. // Let's save it and restore it later. $includePath = get_include_path(); // Run PieCrust dynamically. $pieCrustException = null; try { $params = PieCrustRunner::getPieCrustParameters(array('root' => $this->rootDir, 'cache' => $this->options['cache']), $context->getRequest()->getServerVariables()); $pieCrust = new PieCrust($params); $pieCrust->getConfig()->setValue('server/is_hosting', true); $pieCrust->getConfig()->setValue('site/cache_time', false); $pieCrust->getConfig()->setValue('site/pretty_urls', true); $pieCrust->getConfig()->setValue('site/root', '/'); if ($this->options['debug']) { $pieCrust->getConfig()->setValue('site/display_errors', true); } } catch (Exception $e) { // Error while setting up PieCrust. $pieCrustException = $e; } // If there was no error setting up the application, see if there was // an error in the last pre-bake. if ($pieCrustException == null) { $pieCrustException = $this->bakeError; $this->bakeError = null; } // If there was no error so far, run the current request. $headers = array(); if ($pieCrustException == null) { try { $runner = new PieCrustRunner($pieCrust); $runner->runUnsafe(null, $context->getRequest()->getServerVariables(), null, $headers); } catch (Exception $e) { // Error while running the request. $pieCrustException = $e; } } // Set the return HTTP status code. $code = 500; if (isset($headers[0])) { // The HTTP return code is set by PieCrust in the '0'-th header (if // set at all). $code = $headers[0]; unset($headers[0]); // Unset so we can iterate on headers more easily later. } else { $code = $pieCrustException == null ? 200 : ($pieCrustException->getMessage() == '404' ? 404 : 500); } $context->getResponse()->setStatus($code); // Set the headers. foreach ($headers as $h => $v) { $context->getResponse()->setHeader($h, $v); } // Show an error message, if needed. if ($pieCrustException) { $headers = array(); $handler = new PieCrustErrorHandler($pieCrust); $handler->handleError($pieCrustException, null, $headers); } // Restore the include path. set_include_path($includePath); $endTime = microtime(true); $timeSpan = microtime(true) - $startTime; $context->getLog()->debug("Ran PieCrust request in " . $timeSpan * 1000 . "ms."); if ($pieCrustException != null) { $context->getLog()->error($pieCrustException->getMessage()); } }
/** * Handles an exception by showing an appropriate * error page. */ public function handleError(Exception $e, $server = null, array &$headers = null) { $displayErrors = $this->pieCrust->isDebuggingEnabled() || $this->pieCrust->getConfig()->getValue('site/display_errors'); // If debugging is enabled, just display the error and exit. if ($displayErrors) { if ($e->getMessage() == '404') { //TODO: set header? piecrust_show_system_message('404'); return; } $errorMessage = self::formatException($e, true); piecrust_show_system_message('error', $errorMessage); return; } // First of all, check that we're not running // some completely brand new and un-configured website. if ($this->isEmptySetup()) { piecrust_show_system_message('welcome'); return; } // Generic error message in case we don't have anything custom. $errorMessage = "<p>We're sorry but something very wrong happened, and we don't know what. " . "We'll try to do better next time.</p>" . PHP_EOL; // Get the URI to the custom error page, and the error code. if ($e->getMessage() == '404') { HttpHeaderHelper::setOrAddHeader(0, 404, $headers); $errorPageUri = '_404'; } else { HttpHeaderHelper::setOrAddHeader(0, 500, $headers); $errorPageUri = '_error'; } // Get the error page's info. try { $errorPageUriInfo = UriParser::parseUri($this->pieCrust, $errorPageUri, UriParser::PAGE_URI_REGULAR); } catch (Exception $inner) { // What the f**k. piecrust_show_system_message('critical', $errorMessage); return; } // Render the error page (either a custom one, or a generic one). if ($errorPageUriInfo != null and is_file($errorPageUriInfo['path'])) { // We have a custom error page. Show it, or display // the "fatal error" page if even this doesn't work. try { $runner = new PieCrustRunner($this->pieCrust); $runner->runUnsafe($errorPageUri, $server, null, $headers); } catch (Exception $inner) { // Well there's really something wrong. piecrust_show_system_message('critical', $errorMessage); } } else { // We don't have a custom error page. Just show the generic // error page. $errorMessage = self::formatException($e, false); piecrust_show_system_message(substr($errorPageUri, 1), $errorMessage); } }