Page MenuHomePhabricator

D20138.diff
No OneTemporary

D20138.diff

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
@@ -286,6 +286,7 @@
$original_exception = $ex;
}
+ $response_exception = null;
try {
if ($original_exception) {
$response = $this->handleThrowable($original_exception);
@@ -296,7 +297,13 @@
$response->setRequest($request);
self::writeResponse($sink, $response);
- } catch (Exception $response_exception) {
+ } catch (Exception $ex) {
+ $response_exception = $ex;
+ } catch (Throwable $ex) {
+ $response_exception = $ex;
+ }
+
+ if ($response_exception) {
// If we encountered an exception while building a normal response, then
// encountered another exception while building a response for the first
// exception, just throw the original exception. It is more likely to be
diff --git a/support/startup/PhabricatorStartup.php b/support/startup/PhabricatorStartup.php
--- a/support/startup/PhabricatorStartup.php
+++ b/support/startup/PhabricatorStartup.php
@@ -315,7 +315,7 @@
*
* @param string Brief description of the exception context, like
* `"Rendering Exception"`.
- * @param Exception The exception itself.
+ * @param Throwable The exception itself.
* @param bool True if it's okay to show the exception's stack trace
* to the user. The trace will always be logged.
* @return exit This method **does not return**.
@@ -324,7 +324,7 @@
*/
public static function didEncounterFatalException(
$note,
- Exception $ex,
+ $ex,
$show_trace) {
$message = '['.$note.'/'.get_class($ex).'] '.$ex->getMessage();
diff --git a/webroot/index.php b/webroot/index.php
--- a/webroot/index.php
+++ b/webroot/index.php
@@ -2,6 +2,7 @@
phabricator_startup();
+$fatal_exception = null;
try {
PhabricatorStartup::beginStartupPhase('libraries');
PhabricatorStartup::loadCoreLibraries();
@@ -12,25 +13,65 @@
PhabricatorStartup::beginStartupPhase('sink');
$sink = new AphrontPHPHTTPSink();
+ // PHP introduced a "Throwable" interface in PHP 7 and began making more
+ // runtime errors throw as "Throwable" errors. This is generally good, but
+ // makes top-level exception handling that is compatible with both PHP 5
+ // and PHP 7 a bit tricky.
+
+ // In PHP 5, "Throwable" does not exist, so "catch (Throwable $ex)" catches
+ // nothing.
+
+ // In PHP 7, various runtime conditions raise an Error which is a Throwable
+ // but NOT an Exception, so "catch (Exception $ex)" will not catch them.
+
+ // To cover both cases, we "catch (Exception $ex)" to catch everything in
+ // PHP 5, and most things in PHP 7. Then, we "catch (Throwable $ex)" to catch
+ // everything else in PHP 7. For the most part, we only need to do this at
+ // the top level.
+
+ $main_exception = null;
try {
PhabricatorStartup::beginStartupPhase('run');
AphrontApplicationConfiguration::runHTTPRequest($sink);
} catch (Exception $ex) {
+ $main_exception = $ex;
+ } catch (Throwable $ex) {
+ $main_exception = $ex;
+ }
+
+ if ($main_exception) {
+ $response_exception = null;
try {
$response = new AphrontUnhandledExceptionResponse();
- $response->setException($ex);
+ $response->setException($main_exception);
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;
+ } catch (Exception $ex) {
+ $response_exception = $ex;
+ } catch (Throwable $ex) {
+ $response_exception = $ex;
+ }
+
+ // 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.
+
+ if ($response_exception) {
+ throw $main_exception;
}
}
} catch (Exception $ex) {
- PhabricatorStartup::didEncounterFatalException('Core Exception', $ex, false);
+ $fatal_exception = $ex;
+} catch (Throwable $ex) {
+ $fatal_exception = $ex;
+}
+
+if ($fatal_exception) {
+ PhabricatorStartup::didEncounterFatalException(
+ 'Core Exception',
+ $fatal_exception,
+ false);
}
function phabricator_startup() {

File Metadata

Mime Type
text/plain
Expires
Mon, May 13, 10:25 PM (2 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6277743
Default Alt Text
D20138.diff (4 KB)

Event Timeline