Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15399653
D20138.id48096.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D20138.id48096.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 18, 6:27 AM (5 d, 44 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7639869
Default Alt Text
D20138.id48096.diff (4 KB)
Attached To
Mode
D20138: Improve top-level fatal exception handling in PHP 7+
Attached
Detach File
Event Timeline
Log In to Comment