diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -45,6 +45,7 @@
     'rsrc/css/application/config/config-template.css' => '25d446d6',
     'rsrc/css/application/config/config-welcome.css' => 'b0d16200',
     'rsrc/css/application/config/setup-issue.css' => '8f852bc0',
+    'rsrc/css/application/config/unhandled-exception.css' => '38f08073',
     'rsrc/css/application/conpherence/menu.css' => 'e1e0fdf1',
     'rsrc/css/application/conpherence/message-pane.css' => '042886d1',
     'rsrc/css/application/conpherence/notification.css' => '04a6e10a',
@@ -816,6 +817,7 @@
     'sprite-tokens-css' => '1706b943',
     'syntax-highlighting-css' => '56c1ba38',
     'tokens-css' => '3d0f239e',
+    'unhandled-exception-css' => '38f08073',
   ),
   'requires' => array(
     '00861799' => array(
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -161,12 +161,14 @@
     'AphrontResponse' => 'aphront/response/AphrontResponse.php',
     'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
     'AphrontStackTraceView' => 'view/widget/AphrontStackTraceView.php',
+    'AphrontStandaloneHTMLResponse' => 'aphront/response/AphrontStandaloneHTMLResponse.php',
     'AphrontTableView' => 'view/control/AphrontTableView.php',
     'AphrontTagView' => 'view/AphrontTagView.php',
     'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
     'AphrontTwoColumnView' => 'view/layout/AphrontTwoColumnView.php',
     'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
     'AphrontURIMapper' => 'aphront/AphrontURIMapper.php',
+    'AphrontUnhandledExceptionResponse' => 'aphront/response/AphrontUnhandledExceptionResponse.php',
     'AphrontUsageException' => 'aphront/exception/AphrontUsageException.php',
     'AphrontView' => 'view/AphrontView.php',
     'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
@@ -3217,11 +3219,13 @@
     'AphrontRequestTestCase' => 'PhabricatorTestCase',
     'AphrontSideNavFilterView' => 'AphrontView',
     'AphrontStackTraceView' => 'AphrontView',
+    'AphrontStandaloneHTMLResponse' => 'AphrontHTMLResponse',
     'AphrontTableView' => 'AphrontView',
     'AphrontTagView' => 'AphrontView',
     'AphrontTokenizerTemplateView' => 'AphrontView',
     'AphrontTwoColumnView' => 'AphrontView',
     'AphrontTypeaheadTemplateView' => 'AphrontView',
+    'AphrontUnhandledExceptionResponse' => 'AphrontStandaloneHTMLResponse',
     'AphrontUsageException' => 'AphrontException',
     'AphrontView' => array(
       'Phobject',
@@ -4669,7 +4673,7 @@
       'PhabricatorMarkupInterface',
     ),
     'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
-    'PhabricatorConfigResponse' => 'AphrontHTMLResponse',
+    'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse',
     'PhabricatorConfigSchemaQuery' => 'Phobject',
     'PhabricatorConfigSchemaSpec' => 'Phobject',
     'PhabricatorConfigServerSchema' => 'PhabricatorConfigStorageSchema',
diff --git a/src/__tests__/PhabricatorCelerityTestCase.php b/src/__tests__/PhabricatorCelerityTestCase.php
--- a/src/__tests__/PhabricatorCelerityTestCase.php
+++ b/src/__tests__/PhabricatorCelerityTestCase.php
@@ -15,18 +15,20 @@
       $new_map = id(new CelerityResourceMapGenerator($resources))
         ->generate();
 
-      $this->assertEqual(
-        $new_map->getNameMap(),
-        $old_map->getNameMap());
-      $this->assertEqual(
-        $new_map->getSymbolMap(),
-        $old_map->getSymbolMap());
-      $this->assertEqual(
-        $new_map->getRequiresMap(),
-        $old_map->getRequiresMap());
-      $this->assertEqual(
-        $new_map->getPackageMap(),
-        $old_map->getPackageMap());
+      // Don't actually compare these values with assertEqual(), since the diff
+      // isn't helpful and is often enormously huge.
+
+      $maps_are_identical =
+        ($new_map->getNameMap() === $old_map->getNameMap()) &&
+        ($new_map->getSymbolMap() === $old_map->getSymbolMap()) &&
+        ($new_map->getRequiresMap() === $old_map->getRequiresMap()) &&
+        ($new_map->getPackageMap() === $old_map->getPackageMap());
+
+      $this->assertTrue(
+        $maps_are_identical,
+        pht(
+          'When this test fails, it means the Celerity resource map is out '.
+          'of date. Run `bin/celerity map` to rebuild it.'));
     }
   }
 
diff --git a/src/aphront/configuration/AphrontApplicationConfiguration.php b/src/aphront/configuration/AphrontApplicationConfiguration.php
--- a/src/aphront/configuration/AphrontApplicationConfiguration.php
+++ b/src/aphront/configuration/AphrontApplicationConfiguration.php
@@ -54,6 +54,192 @@
   public function willBuildRequest() {}
 
 
+  /**
+   * @phutil-external-symbol class PhabricatorStartup
+   */
+  public static function runHTTPRequest(AphrontHTTPSink $sink) {
+    PhabricatorEnv::initializeWebEnvironment();
+
+    $debug_time_limit = PhabricatorEnv::getEnvConfig('debug.time-limit');
+    if ($debug_time_limit) {
+      PhabricatorStartup::setDebugTimeLimit($debug_time_limit);
+    }
+
+    // This is the earliest we can get away with this, we need env config first.
+    PhabricatorAccessLog::init();
+    $access_log = PhabricatorAccessLog::getLog();
+    PhabricatorStartup::setGlobal('log.access', $access_log);
+    $access_log->setData(
+      array(
+        'R' => AphrontRequest::getHTTPHeader('Referer', '-'),
+        'r' => idx($_SERVER, 'REMOTE_ADDR', '-'),
+        'M' => idx($_SERVER, 'REQUEST_METHOD', '-'),
+      ));
+
+    DarkConsoleXHProfPluginAPI::hookProfiler();
+    DarkConsoleErrorLogPluginAPI::registerErrorHandler();
+
+    $response = PhabricatorSetupCheck::willProcessRequest();
+    if ($response) {
+      PhabricatorStartup::endOutputCapture();
+      $sink->writeResponse($response);
+      return;
+    }
+
+    $host = AphrontRequest::getHTTPHeader('Host');
+    $path = $_REQUEST['__path__'];
+
+    switch ($host) {
+      default:
+        $config_key = 'aphront.default-application-configuration-class';
+        $application = PhabricatorEnv::newObjectFromConfig($config_key);
+        break;
+    }
+
+    $application->setHost($host);
+    $application->setPath($path);
+    $application->willBuildRequest();
+    $request = $application->buildRequest();
+
+    // Build the server URI implied by the request headers. If an administrator
+    // has not configured "phabricator.base-uri" yet, we'll use this to generate
+    // links.
+
+    $request_protocol = ($request->isHTTPS() ? 'https' : 'http');
+    $request_base_uri = "{$request_protocol}://{$host}/";
+    PhabricatorEnv::setRequestBaseURI($request_base_uri);
+
+    $access_log->setData(
+      array(
+        'U' => (string)$request->getRequestURI()->getPath(),
+      ));
+
+    $write_guard = new AphrontWriteGuard(array($request, 'validateCSRF'));
+
+    $processing_exception = null;
+    try {
+      $response = $application->processRequest($request, $access_log, $sink);
+      $response_code = $response->getHTTPResponseCode();
+    } catch (Exception $ex) {
+      $processing_exception = $ex;
+      $response_code = 500;
+    }
+
+    $write_guard->dispose();
+
+    $access_log->setData(
+      array(
+        'c' => $response_code,
+        'T' => PhabricatorStartup::getMicrosecondsSinceStart(),
+      ));
+
+    $access_log->write();
+
+    DarkConsoleXHProfPluginAPI::saveProfilerSample($access_log);
+
+    // Add points to the rate limits for this request.
+    if (isset($_SERVER['REMOTE_ADDR'])) {
+      $user_ip = $_SERVER['REMOTE_ADDR'];
+
+      // The base score for a request allows users to make 30 requests per
+      // minute.
+      $score = (1000 / 30);
+
+      // If the user was logged in, let them make more requests.
+      if ($request->getUser() && $request->getUser()->getPHID()) {
+        $score = $score / 5;
+      }
+
+      PhabricatorStartup::addRateLimitScore($user_ip, $score);
+    }
+
+    if ($processing_exception) {
+      throw $processing_exception;
+    }
+  }
+
+
+  public function processRequest(
+    AphrontRequest $request,
+    PhutilDeferredLog $access_log,
+    AphrontHTTPSink $sink) {
+
+    $this->setRequest($request);
+
+    list($controller, $uri_data) = $this->buildController();
+
+    $access_log->setData(
+      array(
+        'C' => get_class($controller),
+      ));
+
+    $request->setURIMap($uri_data);
+    $controller->setRequest($request);
+
+    // If execution throws an exception and then trying to render that
+    // exception throws another exception, we want to show the original
+    // exception, as it is likely the root cause of the rendering exception.
+    $original_exception = null;
+    try {
+      $response = $controller->willBeginExecution();
+
+      if ($request->getUser() && $request->getUser()->getPHID()) {
+        $access_log->setData(
+          array(
+            'u' => $request->getUser()->getUserName(),
+            'P' => $request->getUser()->getPHID(),
+          ));
+      }
+
+      if (!$response) {
+        $controller->willProcessRequest($uri_data);
+        $response = $controller->handleRequest($request);
+      }
+    } catch (Exception $ex) {
+      $original_exception = $ex;
+      $response = $this->handleException($ex);
+    }
+
+    try {
+      $response = $controller->didProcessRequest($response);
+      $response = $this->willSendResponse($response, $controller);
+      $response->setRequest($request);
+
+      $unexpected_output = PhabricatorStartup::endOutputCapture();
+      if ($unexpected_output) {
+        $unexpected_output = pht(
+          "Unexpected output:\n\n%s",
+          $unexpected_output);
+
+        phlog($unexpected_output);
+
+        if ($response instanceof AphrontWebpageResponse) {
+          echo phutil_tag(
+            'div',
+            array('style' =>
+              'background: #eeddff;'.
+              'white-space: pre-wrap;'.
+              'z-index: 200000;'.
+              'position: relative;'.
+              'padding: 8px;'.
+              'font-family: monospace',
+            ),
+            $unexpected_output);
+        }
+      }
+
+      $sink->writeResponse($response);
+    } catch (Exception $ex) {
+      if ($original_exception) {
+        throw $original_exception;
+      }
+      throw $ex;
+    }
+
+    return $response;
+  }
+
+
 /* -(  URI Routing  )-------------------------------------------------------- */
 
 
diff --git a/src/aphront/response/AphrontStandaloneHTMLResponse.php b/src/aphront/response/AphrontStandaloneHTMLResponse.php
new file mode 100644
--- /dev/null
+++ b/src/aphront/response/AphrontStandaloneHTMLResponse.php
@@ -0,0 +1,63 @@
+<?php
+
+abstract class AphrontStandaloneHTMLResponse
+  extends AphrontHTMLResponse {
+
+  abstract protected function getResources();
+  abstract protected function getResponseTitle();
+  abstract protected function getResponseBodyClass();
+  abstract protected function getResponseBody();
+  abstract protected function buildPlainTextResponseString();
+
+  final public function buildResponseString() {
+    // Check to make sure we aren't requesting this via Ajax or Conduit.
+    if (isset($_REQUEST['__ajax__']) || isset($_REQUEST['__conduit__'])) {
+      return (string)hsprintf('%s', $this->buildPlainTextResponseString());
+    }
+
+    $title = $this->getResponseTitle();
+    $resources = $this->buildResources();
+    $body_class = $this->getResponseBodyClass();
+    $body = $this->getResponseBody();
+
+    return (string)hsprintf(
+<<<EOTEMPLATE
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8" />
+    <title>%s</title>
+    %s
+  </head>
+  %s
+</html>
+EOTEMPLATE
+      ,
+      $title,
+      $resources,
+      phutil_tag(
+        'body',
+        array(
+          'class' => $body_class,
+        ),
+        $body));
+  }
+
+  private function buildResources() {
+    $paths = $this->getResources();
+
+    $webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
+
+    $resources = array();
+    foreach ($paths as $path) {
+      $resources[] = phutil_tag(
+        'style',
+        array('type' => 'text/css'),
+        phutil_safe_html(Filesystem::readFile($webroot.'/rsrc/'.$path)));
+    }
+
+    return phutil_implode_html("\n", $resources);
+  }
+
+
+}
diff --git a/src/aphront/response/AphrontUnhandledExceptionResponse.php b/src/aphront/response/AphrontUnhandledExceptionResponse.php
new file mode 100644
--- /dev/null
+++ b/src/aphront/response/AphrontUnhandledExceptionResponse.php
@@ -0,0 +1,74 @@
+<?php
+
+final class AphrontUnhandledExceptionResponse
+  extends AphrontStandaloneHTMLResponse {
+
+  private $exception;
+
+  public function setException(Exception $exception) {
+    $this->exception = $exception;
+    return $this;
+  }
+
+  public function getHTTPResponseCode() {
+    return 500;
+  }
+
+  protected function getResources() {
+    return array(
+      'css/application/config/config-template.css',
+      'css/application/config/unhandled-exception.css',
+    );
+  }
+
+  protected function getResponseTitle() {
+    return pht('Unhandled Exception');
+  }
+
+  protected function getResponseBodyClass() {
+    return 'unhandled-exception';
+  }
+
+  protected function getResponseBody() {
+    $ex = $this->exception;
+
+    if ($ex instanceof AphrontUsageException) {
+      $title = $ex->getTitle();
+    } else {
+      $title = get_class($ex);
+    }
+
+    $body = $ex->getMessage();
+    $body = phutil_escape_html_newlines($body);
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'unhandled-exception-detail',
+      ),
+      array(
+        phutil_tag(
+          'h1',
+          array(
+            'class' => 'unhandled-exception-title',
+          ),
+          $title),
+        phutil_tag(
+          'div',
+          array(
+            'class' => 'unhandled-exception-body',
+          ),
+          $body),
+      ));
+  }
+
+  protected function buildPlainTextResponseString() {
+    $ex = $this->exception;
+
+    return pht(
+      '%s: %s',
+      get_class($ex),
+      $ex->getMessage());
+  }
+
+}
diff --git a/src/applications/config/response/PhabricatorConfigResponse.php b/src/applications/config/response/PhabricatorConfigResponse.php
--- a/src/applications/config/response/PhabricatorConfigResponse.php
+++ b/src/applications/config/response/PhabricatorConfigResponse.php
@@ -1,6 +1,6 @@
 <?php
 
-final class PhabricatorConfigResponse extends AphrontHTMLResponse {
+final class PhabricatorConfigResponse extends AphrontStandaloneHTMLResponse {
 
   private $view;
 
@@ -9,51 +9,33 @@
     return $this;
   }
 
-  public function buildResponseString() {
-    // Check to make sure we aren't requesting this via ajax or conduit
-    if (isset($_REQUEST['__ajax__']) || isset($_REQUEST['__conduit__'])) {
-      // We don't want to flood the console with html, just return a simple
-      // message for now.
-      return pht(
-        'This install has a fatal setup error, access the internet web '.
-        'version to view details and resolve it.');
-    }
-
-    $resources = $this->buildResources();
-
-    $view = $this->view->render();
-
-    return hsprintf(
-      '<!DOCTYPE html>'.
-      '<html>'.
-        '<head>'.
-          '<meta charset="UTF-8" />'.
-          '<title>Phabricator Setup</title>'.
-          '%s'.
-        '</head>'.
-        '<body class="setup-fatal">%s</body>'.
-      '</html>',
-      $resources,
-      $view);
+  public function getHTTPResponseCode() {
+    return 500;
   }
 
-  private function buildResources() {
-    $css = array(
-      'application/config/config-template.css',
-      'application/config/setup-issue.css',
+  protected function getResources() {
+    return array(
+      'css/application/config/config-template.css',
+      'css/application/config/setup-issue.css',
     );
+  }
 
-    $webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
+  protected function getResponseTitle() {
+    return pht('Phabricator Setup Error');
+  }
 
-    $resources = array();
-    foreach ($css as $path) {
-      $resources[] = phutil_tag(
-        'style',
-        array('type' => 'text/css'),
-        phutil_safe_html(Filesystem::readFile($webroot.'/rsrc/css/'.$path)));
-    }
-    return phutil_implode_html("\n", $resources);
+  protected function getResponseBodyClass() {
+    return 'setup-fatal';
   }
 
+  protected function getResponseBody() {
+    return $this->view->render();
+  }
+
+  protected function buildPlainTextResponseString() {
+    return pht(
+      'This install has a fatal setup error, access the internet web '.
+      'version to view details and resolve it.');
+  }
 
 }
diff --git a/support/PhabricatorStartup.php b/support/PhabricatorStartup.php
--- a/support/PhabricatorStartup.php
+++ b/support/PhabricatorStartup.php
@@ -122,6 +122,10 @@
     self::setupPHP();
     self::verifyPHP();
 
+    // If we've made it this far, the environment isn't completely broken so
+    // we can switch over to relying on our own exception recovery mechanisms.
+    ini_set('display_errors', 0);
+
     if (isset($_SERVER['REMOTE_ADDR'])) {
       self::rateLimitRequest($_SERVER['REMOTE_ADDR']);
     }
diff --git a/webroot/index.php b/webroot/index.php
--- a/webroot/index.php
+++ b/webroot/index.php
@@ -11,174 +11,27 @@
 
 PhabricatorStartup::didStartup();
 
-$show_unexpected_traces = false;
 try {
   PhabricatorStartup::loadCoreLibraries();
-
-  PhabricatorEnv::initializeWebEnvironment();
-
-  $debug_time_limit = PhabricatorEnv::getEnvConfig('debug.time-limit');
-  if ($debug_time_limit) {
-    PhabricatorStartup::setDebugTimeLimit($debug_time_limit);
-  }
-
-  $show_unexpected_traces = PhabricatorEnv::getEnvConfig(
-    'phabricator.developer-mode');
-
-  // This is the earliest we can get away with this, we need env config first.
-  PhabricatorAccessLog::init();
-  $access_log = PhabricatorAccessLog::getLog();
-  PhabricatorStartup::setGlobal('log.access', $access_log);
-  $access_log->setData(
-    array(
-      'R' => AphrontRequest::getHTTPHeader('Referer', '-'),
-      'r' => idx($_SERVER, 'REMOTE_ADDR', '-'),
-      'M' => idx($_SERVER, 'REQUEST_METHOD', '-'),
-    ));
-
-  DarkConsoleXHProfPluginAPI::hookProfiler();
-  DarkConsoleErrorLogPluginAPI::registerErrorHandler();
-
   $sink = new AphrontPHPHTTPSink();
 
-  $response = PhabricatorSetupCheck::willProcessRequest();
-  if ($response) {
-    PhabricatorStartup::endOutputCapture();
-    $sink->writeResponse($response);
-    return;
-  }
-
-  $host = AphrontRequest::getHTTPHeader('Host');
-  $path = $_REQUEST['__path__'];
-
-  switch ($host) {
-    default:
-      $config_key = 'aphront.default-application-configuration-class';
-      $application = PhabricatorEnv::newObjectFromConfig($config_key);
-      break;
-  }
-
-  $application->setHost($host);
-  $application->setPath($path);
-  $application->willBuildRequest();
-  $request = $application->buildRequest();
-
-  // Until an administrator sets "phabricator.base-uri", assume it is the same
-  // as the request URI. This will work fine in most cases, it just breaks down
-  // when daemons need to do things.
-  $request_protocol = ($request->isHTTPS() ? 'https' : 'http');
-  $request_base_uri = "{$request_protocol}://{$host}/";
-  PhabricatorEnv::setRequestBaseURI($request_base_uri);
-
-  $write_guard = new AphrontWriteGuard(array($request, 'validateCSRF'));
-
-  $application->setRequest($request);
-  list($controller, $uri_data) = $application->buildController();
-  $request->setURIMap($uri_data);
-  $controller->setRequest($request);
-
-  $access_log->setData(
-    array(
-      'U' => (string)$request->getRequestURI()->getPath(),
-      'C' => get_class($controller),
-    ));
-
-  // If execution throws an exception and then trying to render that exception
-  // throws another exception, we want to show the original exception, as it is
-  // likely the root cause of the rendering exception.
-  $original_exception = null;
-  try {
-    $response = $controller->willBeginExecution();
-
-    if ($request->getUser() && $request->getUser()->getPHID()) {
-      $access_log->setData(
-        array(
-          'u' => $request->getUser()->getUserName(),
-          'P' => $request->getUser()->getPHID(),
-        ));
-    }
-
-    if (!$response) {
-      $controller->willProcessRequest($uri_data);
-      $response = $controller->handleRequest($request);
-    }
-  } catch (Exception $ex) {
-    $original_exception = $ex;
-    $response = $application->handleException($ex);
-  }
-
   try {
-    $response = $controller->didProcessRequest($response);
-    $response = $application->willSendResponse($response, $controller);
-    $response->setRequest($request);
-
-    $unexpected_output = PhabricatorStartup::endOutputCapture();
-    if ($unexpected_output) {
-      $unexpected_output = "Unexpected output:\n\n{$unexpected_output}";
-      phlog($unexpected_output);
-
-      if ($response instanceof AphrontWebpageResponse) {
-        echo phutil_tag(
-          'div',
-          array('style' =>
-            'background: #eeddff;'.
-            'white-space: pre-wrap;'.
-            'z-index: 200000;'.
-            'position: relative;'.
-            'padding: 8px;'.
-            'font-family: monospace',
-          ),
-          $unexpected_output);
-      }
-    }
-
-    $sink->writeResponse($response);
+    AphrontApplicationConfiguration::runHTTPRequest($sink);
   } catch (Exception $ex) {
-    $write_guard->dispose();
-    $access_log->write();
-    if ($original_exception) {
-      $ex = new PhutilAggregateException(
-        'Multiple exceptions during processing and rendering.',
-        array(
-          $original_exception,
-          $ex,
-        ));
+    try {
+      $response = new AphrontUnhandledExceptionResponse();
+      $response->setException($ex);
+
+      PhabricatorStartup::endOutputCapture();
+      $sink->writeResponse($response);
+    } catch (Exception $response_exception) {
+      // If we hit a rendering exception, ignore it and throw the original
+      // exception. It is generally more interesting and more likely to be
+      // the root cause.
+      throw $ex;
     }
-    PhabricatorStartup::didEncounterFatalException(
-      'Rendering Exception',
-      $ex,
-      $show_unexpected_traces);
-  }
-
-  $write_guard->dispose();
-
-  $access_log->setData(
-    array(
-      'c' => $response->getHTTPResponseCode(),
-      'T' => PhabricatorStartup::getMicrosecondsSinceStart(),
-    ));
-
-  DarkConsoleXHProfPluginAPI::saveProfilerSample($access_log);
-
-  // Add points to the rate limits for this request.
-  if (isset($_SERVER['REMOTE_ADDR'])) {
-    $user_ip = $_SERVER['REMOTE_ADDR'];
-
-    // The base score for a request allows users to make 30 requests per
-    // minute.
-    $score = (1000 / 30);
-
-    // If the user was logged in, let them make more requests.
-    if ($request->getUser() && $request->getUser()->getPHID()) {
-      $score = $score / 5;
-    }
-
-    PhabricatorStartup::addRateLimitScore($user_ip, $score);
   }
 
 } catch (Exception $ex) {
-  PhabricatorStartup::didEncounterFatalException(
-    'Core Exception',
-    $ex,
-    $show_unexpected_traces);
+  PhabricatorStartup::didEncounterFatalException('Core Exception', $ex, false);
 }
diff --git a/webroot/rsrc/css/application/config/unhandled-exception.css b/webroot/rsrc/css/application/config/unhandled-exception.css
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/css/application/config/unhandled-exception.css
@@ -0,0 +1,27 @@
+/**
+ * @provides unhandled-exception-css
+ */
+
+.unhandled-exception {
+  background: #222228;
+}
+
+.unhandled-exception-detail {
+  max-width: 760px;
+  margin: 16px auto;
+  background: #f7f7f7;
+  border: 2px solid #ffffff;
+}
+
+.unhandled-exception-detail .unhandled-exception-title {
+  font-size: 15px;
+  font-weight: bold;
+  margin: 0;
+  padding: 16px;
+  background: #DFE0E2;
+}
+
+.unhandled-exception-detail .unhandled-exception-body {
+  padding: 16px;
+  color: #4B4D51;
+}