Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/aphront/configuration/AphrontApplicationConfiguration.php b/src/aphront/configuration/AphrontApplicationConfiguration.php
index b89feaebb5..c0cd259992 100644
--- a/src/aphront/configuration/AphrontApplicationConfiguration.php
+++ b/src/aphront/configuration/AphrontApplicationConfiguration.php
@@ -1,718 +1,721 @@
<?php
/**
* @task routing URI Routing
* @task response Response Handling
* @task exception Exception Handling
*/
abstract class AphrontApplicationConfiguration extends Phobject {
private $request;
private $host;
private $path;
private $console;
abstract public function buildRequest();
abstract public function build404Controller();
abstract public function buildRedirectController($uri, $external);
final public function setRequest(AphrontRequest $request) {
$this->request = $request;
return $this;
}
final public function getRequest() {
return $this->request;
}
final public function getConsole() {
return $this->console;
}
final public function setConsole($console) {
$this->console = $console;
return $this;
}
final public function setHost($host) {
$this->host = $host;
return $this;
}
final public function getHost() {
return $this->host;
}
final public function setPath($path) {
$this->path = $path;
return $this;
}
final public function getPath() {
return $this->path;
}
public function willBuildRequest() {}
/**
* @phutil-external-symbol class PhabricatorStartup
*/
public static function runHTTPRequest(AphrontHTTPSink $sink) {
if (isset($_SERVER['HTTP_X_PHABRICATOR_SELFCHECK'])) {
$response = self::newSelfCheckResponse();
return self::writeResponse($sink, $response);
}
PhabricatorStartup::beginStartupPhase('multimeter');
$multimeter = MultimeterControl::newInstance();
$multimeter->setEventContext('<http-init>');
$multimeter->setEventViewer('<none>');
// Build a no-op write guard for the setup phase. We'll replace this with a
// real write guard later on, but we need to survive setup and build a
// request object first.
$write_guard = new AphrontWriteGuard('id');
PhabricatorStartup::beginStartupPhase('preflight');
$response = PhabricatorSetupCheck::willPreflightRequest();
if ($response) {
return self::writeResponse($sink, $response);
}
PhabricatorStartup::beginStartupPhase('env.init');
try {
PhabricatorEnv::initializeWebEnvironment();
$database_exception = null;
} catch (PhabricatorClusterStrandedException $ex) {
$database_exception = $ex;
}
if ($database_exception) {
$issue = PhabricatorSetupIssue::newDatabaseConnectionIssue(
$database_exception,
true);
$response = PhabricatorSetupCheck::newIssueResponse($issue);
return self::writeResponse($sink, $response);
}
$multimeter->setSampleRate(
PhabricatorEnv::getEnvConfig('debug.sample-rate'));
$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.
PhabricatorStartup::beginStartupPhase('log.access');
PhabricatorAccessLog::init();
$access_log = PhabricatorAccessLog::getLog();
PhabricatorStartup::setAccessLog($access_log);
$address = PhabricatorEnv::getRemoteAddress();
if ($address) {
$address_string = $address->getAddress();
} else {
$address_string = '-';
}
$access_log->setData(
array(
'R' => AphrontRequest::getHTTPHeader('Referer', '-'),
'r' => $address_string,
'M' => idx($_SERVER, 'REQUEST_METHOD', '-'),
));
DarkConsoleXHProfPluginAPI::hookProfiler();
// We just activated the profiler, so we don't need to keep track of
// startup phases anymore: it can take over from here.
PhabricatorStartup::beginStartupPhase('startup.done');
DarkConsoleErrorLogPluginAPI::registerErrorHandler();
$response = PhabricatorSetupCheck::willProcessRequest();
if ($response) {
return self::writeResponse($sink, $response);
}
$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();
// Now that we have a request, convert the write guard into one which
// actually checks CSRF tokens.
$write_guard->dispose();
$write_guard = new AphrontWriteGuard(array($request, 'validateCSRF'));
// 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(),
));
$processing_exception = null;
try {
$response = $application->processRequest(
$request,
$access_log,
$sink,
$multimeter);
$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(),
));
$multimeter->newEvent(
MultimeterEvent::TYPE_REQUEST_TIME,
$multimeter->getEventContext(),
PhabricatorStartup::getMicrosecondsSinceStart());
$access_log->write();
$multimeter->saveEvents();
DarkConsoleXHProfPluginAPI::saveProfilerSample($access_log);
// Add points to the rate limits for this request.
$rate_token = PhabricatorStartup::getRateLimitToken();
if ($rate_token !== null) {
// 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($rate_token, $score);
}
if ($processing_exception) {
throw $processing_exception;
}
}
public function processRequest(
AphrontRequest $request,
PhutilDeferredLog $access_log,
AphrontHTTPSink $sink,
MultimeterControl $multimeter) {
$this->setRequest($request);
list($controller, $uri_data) = $this->buildController();
$controller_class = get_class($controller);
$access_log->setData(
array(
'C' => $controller_class,
));
$multimeter->setEventContext('web.'.$controller_class);
$request->setController($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(),
));
$multimeter->setEventViewer('user.'.$request->getUser()->getPHID());
}
if (!$response) {
$controller->willProcessRequest($uri_data);
$response = $controller->handleRequest($request);
$this->validateControllerResponse($controller, $response);
}
} catch (Exception $ex) {
$original_exception = $ex;
- $response = $this->handleException($ex);
+ $response = $this->handleThrowable($ex);
+ } catch (Throwable $ex) {
+ $original_exception = $ex;
+ $response = $this->handleThrowable($ex);
}
try {
$response = $this->produceResponse($request, $response);
$response = $controller->willSendResponse($response);
$response->setRequest($request);
self::writeResponse($sink, $response);
} catch (Exception $ex) {
if ($original_exception) {
throw $original_exception;
}
throw $ex;
}
return $response;
}
private static function writeResponse(
AphrontHTTPSink $sink,
AphrontResponse $response) {
$unexpected_output = PhabricatorStartup::endOutputCapture();
if ($unexpected_output) {
$unexpected_output = pht(
"Unexpected output:\n\n%s",
$unexpected_output);
phlog($unexpected_output);
if ($response instanceof AphrontWebpageResponse) {
$response->setUnexpectedOutput($unexpected_output);
}
}
$sink->writeResponse($response);
}
/* -( URI Routing )-------------------------------------------------------- */
/**
* Build a controller to respond to the request.
*
* @return pair<AphrontController,dict> Controller and dictionary of request
* parameters.
* @task routing
*/
final private function buildController() {
$request = $this->getRequest();
// If we're configured to operate in cluster mode, reject requests which
// were not received on a cluster interface.
//
// For example, a host may have an internal address like "170.0.0.1", and
// also have a public address like "51.23.95.16". Assuming the cluster
// is configured on a range like "170.0.0.0/16", we want to reject the
// requests received on the public interface.
//
// Ideally, nodes in a cluster should only be listening on internal
// interfaces, but they may be configured in such a way that they also
// listen on external interfaces, since this is easy to forget about or
// get wrong. As a broad security measure, reject requests received on any
// interfaces which aren't on the whitelist.
$cluster_addresses = PhabricatorEnv::getEnvConfig('cluster.addresses');
if ($cluster_addresses) {
$server_addr = idx($_SERVER, 'SERVER_ADDR');
if (!$server_addr) {
if (php_sapi_name() == 'cli') {
// This is a command line script (probably something like a unit
// test) so it's fine that we don't have SERVER_ADDR defined.
} else {
throw new AphrontMalformedRequestException(
pht('No %s', 'SERVER_ADDR'),
pht(
'Phabricator is configured to operate in cluster mode, but '.
'%s is not defined in the request context. Your webserver '.
'configuration needs to forward %s to PHP so Phabricator can '.
'reject requests received on external interfaces.',
'SERVER_ADDR',
'SERVER_ADDR'));
}
} else {
if (!PhabricatorEnv::isClusterAddress($server_addr)) {
throw new AphrontMalformedRequestException(
pht('External Interface'),
pht(
'Phabricator is configured in cluster mode and the address '.
'this request was received on ("%s") is not whitelisted as '.
'a cluster address.',
$server_addr));
}
}
}
$site = $this->buildSiteForRequest($request);
if ($site->shouldRequireHTTPS()) {
if (!$request->isHTTPS()) {
// Don't redirect intracluster requests: doing so drops headers and
// parameters, imposes a performance penalty, and indicates a
// misconfiguration.
if ($request->isProxiedClusterRequest()) {
throw new AphrontMalformedRequestException(
pht('HTTPS Required'),
pht(
'This request reached a site which requires HTTPS, but the '.
'request is not marked as HTTPS.'));
}
$https_uri = $request->getRequestURI();
$https_uri->setDomain($request->getHost());
$https_uri->setProtocol('https');
// In this scenario, we'll be redirecting to HTTPS using an absolute
// URI, so we need to permit an external redirect.
return $this->buildRedirectController($https_uri, true);
}
}
$maps = $site->getRoutingMaps();
$path = $request->getPath();
$result = $this->routePath($maps, $path);
if ($result) {
return $result;
}
// If we failed to match anything but don't have a trailing slash, try
// to add a trailing slash and issue a redirect if that resolves.
// NOTE: We only do this for GET, since redirects switch to GET and drop
// data like POST parameters.
if (!preg_match('@/$@', $path) && $request->isHTTPGet()) {
$result = $this->routePath($maps, $path.'/');
if ($result) {
$target_uri = $request->getAbsoluteRequestURI();
// We need to restore URI encoding because the webserver has
// interpreted it. For example, this allows us to redirect a path
// like `/tag/aa%20bb` to `/tag/aa%20bb/`, which may eventually be
// resolved meaningfully by an application.
$target_path = phutil_escape_uri($path.'/');
$target_uri->setPath($target_path);
$target_uri = (string)$target_uri;
return $this->buildRedirectController($target_uri, true);
}
}
$result = $site->new404Controller($request);
if ($result) {
return array($result, array());
}
return $this->build404Controller();
}
/**
* Map a specific path to the corresponding controller. For a description
* of routing, see @{method:buildController}.
*
* @param list<AphrontRoutingMap> List of routing maps.
* @param string Path to route.
* @return pair<AphrontController,dict> Controller and dictionary of request
* parameters.
* @task routing
*/
private function routePath(array $maps, $path) {
foreach ($maps as $map) {
$result = $map->routePath($path);
if ($result) {
return array($result->getController(), $result->getURIData());
}
}
}
private function buildSiteForRequest(AphrontRequest $request) {
$sites = PhabricatorSite::getAllSites();
$site = null;
foreach ($sites as $candidate) {
$site = $candidate->newSiteForRequest($request);
if ($site) {
break;
}
}
if (!$site) {
$path = $request->getPath();
$host = $request->getHost();
throw new AphrontMalformedRequestException(
pht('Site Not Found'),
pht(
'This request asked for "%s" on host "%s", but no site is '.
'configured which can serve this request.',
$path,
$host),
true);
}
$request->setSite($site);
return $site;
}
/* -( Response Handling )-------------------------------------------------- */
/**
* Tests if a response is of a valid type.
*
* @param wild Supposedly valid response.
* @return bool True if the object is of a valid type.
* @task response
*/
private function isValidResponseObject($response) {
if ($response instanceof AphrontResponse) {
return true;
}
if ($response instanceof AphrontResponseProducerInterface) {
return true;
}
return false;
}
/**
* Verifies that the return value from an @{class:AphrontController} is
* of an allowed type.
*
* @param AphrontController Controller which returned the response.
* @param wild Supposedly valid response.
* @return void
* @task response
*/
private function validateControllerResponse(
AphrontController $controller,
$response) {
if ($this->isValidResponseObject($response)) {
return;
}
throw new Exception(
pht(
'Controller "%s" returned an invalid response from call to "%s". '.
'This method must return an object of class "%s", or an object '.
'which implements the "%s" interface.',
get_class($controller),
'handleRequest()',
'AphrontResponse',
'AphrontResponseProducerInterface'));
}
/**
* Verifies that the return value from an
* @{class:AphrontResponseProducerInterface} is of an allowed type.
*
* @param AphrontResponseProducerInterface Object which produced
* this response.
* @param wild Supposedly valid response.
* @return void
* @task response
*/
private function validateProducerResponse(
AphrontResponseProducerInterface $producer,
$response) {
if ($this->isValidResponseObject($response)) {
return;
}
throw new Exception(
pht(
'Producer "%s" returned an invalid response from call to "%s". '.
'This method must return an object of class "%s", or an object '.
'which implements the "%s" interface.',
get_class($producer),
'produceAphrontResponse()',
'AphrontResponse',
'AphrontResponseProducerInterface'));
}
/**
* Verifies that the return value from an
* @{class:AphrontRequestExceptionHandler} is of an allowed type.
*
* @param AphrontRequestExceptionHandler Object which produced this
* response.
* @param wild Supposedly valid response.
* @return void
* @task response
*/
private function validateErrorHandlerResponse(
AphrontRequestExceptionHandler $handler,
$response) {
if ($this->isValidResponseObject($response)) {
return;
}
throw new Exception(
pht(
'Exception handler "%s" returned an invalid response from call to '.
'"%s". This method must return an object of class "%s", or an object '.
'which implements the "%s" interface.',
get_class($handler),
'handleRequestException()',
'AphrontResponse',
'AphrontResponseProducerInterface'));
}
/**
* Resolves a response object into an @{class:AphrontResponse}.
*
* Controllers are permitted to return actual responses of class
* @{class:AphrontResponse}, or other objects which implement
* @{interface:AphrontResponseProducerInterface} and can produce a response.
*
* If a controller returns a response producer, invoke it now and produce
* the real response.
*
* @param AphrontRequest Request being handled.
* @param AphrontResponse|AphrontResponseProducerInterface Response, or
* response producer.
* @return AphrontResponse Response after any required production.
* @task response
*/
private function produceResponse(AphrontRequest $request, $response) {
$original = $response;
// Detect cycles on the exact same objects. It's still possible to produce
// infinite responses as long as they're all unique, but we can only
// reasonably detect cycles, not guarantee that response production halts.
$seen = array();
while (true) {
// NOTE: It is permissible for an object to be both a response and a
// response producer. If so, being a producer is "stronger". This is
// used by AphrontProxyResponse.
// If this response is a valid response, hand over the request first.
if ($response instanceof AphrontResponse) {
$response->setRequest($request);
}
// If this isn't a producer, we're all done.
if (!($response instanceof AphrontResponseProducerInterface)) {
break;
}
$hash = spl_object_hash($response);
if (isset($seen[$hash])) {
throw new Exception(
pht(
'Failure while producing response for object of class "%s": '.
'encountered production cycle (identical object, of class "%s", '.
'was produced twice).',
get_class($original),
get_class($response)));
}
$seen[$hash] = true;
$new_response = $response->produceAphrontResponse();
$this->validateProducerResponse($response, $new_response);
$response = $new_response;
}
return $response;
}
/* -( Error Handling )----------------------------------------------------- */
/**
* Convert an exception which has escaped the controller into a response.
*
* This method delegates exception handling to available subclasses of
* @{class:AphrontRequestExceptionHandler}.
*
- * @param Exception Exception which needs to be handled.
+ * @param Throwable Exception which needs to be handled.
* @return wild Response or response producer, or null if no available
* handler can produce a response.
* @task exception
*/
- private function handleException(Exception $ex) {
+ private function handleThrowable($throwable) {
$handlers = AphrontRequestExceptionHandler::getAllHandlers();
$request = $this->getRequest();
foreach ($handlers as $handler) {
- if ($handler->canHandleRequestException($request, $ex)) {
- $response = $handler->handleRequestException($request, $ex);
+ if ($handler->canHandleRequestThrowable($request, $throwable)) {
+ $response = $handler->handleRequestThrowable($request, $throwable);
$this->validateErrorHandlerResponse($handler, $response);
return $response;
}
}
- throw $ex;
+ throw $throwable;
}
private static function newSelfCheckResponse() {
$path = idx($_REQUEST, '__path__', '');
$query = idx($_SERVER, 'QUERY_STRING', '');
$pairs = id(new PhutilQueryStringParser())
->parseQueryStringToPairList($query);
$params = array();
foreach ($pairs as $v) {
$params[] = array(
'name' => $v[0],
'value' => $v[1],
);
}
$result = array(
'path' => $path,
'params' => $params,
'user' => idx($_SERVER, 'PHP_AUTH_USER'),
'pass' => idx($_SERVER, 'PHP_AUTH_PW'),
// This just makes sure that the response compresses well, so reasonable
// algorithms should want to gzip or deflate it.
'filler' => str_repeat('Q', 1024 * 16),
);
return id(new AphrontJSONResponse())
->setAddJSONShield(false)
->setContent($result);
}
}
diff --git a/src/aphront/handler/AphrontRequestExceptionHandler.php b/src/aphront/handler/AphrontRequestExceptionHandler.php
index 694071e1ba..e626f53cc6 100644
--- a/src/aphront/handler/AphrontRequestExceptionHandler.php
+++ b/src/aphront/handler/AphrontRequestExceptionHandler.php
@@ -1,36 +1,30 @@
<?php
/**
* React to an unhandled exception escaping request handling in a controller
* and convert it into a response.
*
* These handlers are generally used to render error pages, but they may
* also perform more specialized handling in situations where an error page
* is not appropriate.
*/
abstract class AphrontRequestExceptionHandler extends Phobject {
abstract public function getRequestExceptionHandlerPriority();
- public function shouldLogException(
+ abstract public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
- return null;
- }
-
- abstract public function canHandleRequestException(
- AphrontRequest $request,
- Exception $ex);
+ $throwable);
- abstract public function handleRequestException(
+ abstract public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex);
+ $throwable);
final public static function getAllHandlers() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setSortMethod('getRequestExceptionHandlerPriority')
->execute();
}
}
diff --git a/src/aphront/handler/PhabricatorAjaxRequestExceptionHandler.php b/src/aphront/handler/PhabricatorAjaxRequestExceptionHandler.php
index 06023e02de..d519c83fb5 100644
--- a/src/aphront/handler/PhabricatorAjaxRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorAjaxRequestExceptionHandler.php
@@ -1,38 +1,39 @@
<?php
final class PhabricatorAjaxRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 110000;
}
public function getRequestExceptionHandlerDescription() {
return pht('Responds to requests made by AJAX clients.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
// For non-workflow requests, return a Ajax response.
return ($request->isAjax() && !$request->isWorkflow());
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
// Log these; they don't get shown on the client and can be difficult
// to debug.
- phlog($ex);
+ phlog($throwable);
$response = new AphrontAjaxResponse();
$response->setError(
array(
- 'code' => get_class($ex),
- 'info' => $ex->getMessage(),
+ 'code' => get_class($throwable),
+ 'info' => $throwable->getMessage(),
));
+
return $response;
}
}
diff --git a/src/aphront/handler/PhabricatorConduitRequestExceptionHandler.php b/src/aphront/handler/PhabricatorConduitRequestExceptionHandler.php
index 367f607f83..db8a5d5ecc 100644
--- a/src/aphront/handler/PhabricatorConduitRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorConduitRequestExceptionHandler.php
@@ -1,33 +1,33 @@
<?php
final class PhabricatorConduitRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 100000;
}
public function getRequestExceptionHandlerDescription() {
return pht('Responds to requests made by Conduit clients.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
return $request->isConduit();
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$response = id(new ConduitAPIResponse())
- ->setErrorCode(get_class($ex))
- ->setErrorInfo($ex->getMessage());
+ ->setErrorCode(get_class($throwable))
+ ->setErrorInfo($throwable->getMessage());
return id(new AphrontJSONResponse())
->setAddJSONShield(false)
->setContent($response->toDictionary());
}
}
diff --git a/src/aphront/handler/PhabricatorDefaultRequestExceptionHandler.php b/src/aphront/handler/PhabricatorDefaultRequestExceptionHandler.php
index d330cd5f2c..b13100b05d 100644
--- a/src/aphront/handler/PhabricatorDefaultRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorDefaultRequestExceptionHandler.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorDefaultRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 900000;
}
public function getRequestExceptionHandlerDescription() {
return pht('Handles all other exceptions.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
if (!$this->isPhabricatorSite($request)) {
return false;
}
return true;
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$viewer = $this->getViewer($request);
// Some types of uninteresting request exceptions don't get logged, usually
// because they are caused by the background radiation of bot traffic on
// the internet. These include requests with bad CSRF tokens and
// questionable "Host" headers.
$should_log = true;
- if ($ex instanceof AphrontMalformedRequestException) {
- $should_log = !$ex->getIsUnlogged();
+ if ($throwable instanceof AphrontMalformedRequestException) {
+ $should_log = !$throwable->getIsUnlogged();
}
if ($should_log) {
- phlog($ex);
+ phlog($throwable);
}
- $class = get_class($ex);
- $message = $ex->getMessage();
+ $class = get_class($throwable);
+ $message = $throwable->getMessage();
- if ($ex instanceof AphrontSchemaQueryException) {
+ if ($throwable instanceof AphrontSchemaQueryException) {
$message .= "\n\n".pht(
"NOTE: This usually indicates that the MySQL schema has not been ".
"properly upgraded. Run '%s' to ensure your schema is up to date.",
'bin/storage upgrade');
}
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
$trace = id(new AphrontStackTraceView())
->setUser($viewer)
- ->setTrace($ex->getTrace());
+ ->setTrace($throwable->getTrace());
} else {
$trace = null;
}
$content = phutil_tag(
'div',
array('class' => 'aphront-unhandled-exception'),
array(
phutil_tag('div', array('class' => 'exception-message'), $message),
$trace,
));
$dialog = new AphrontDialogView();
$dialog
->setTitle(pht('Unhandled Exception ("%s")', $class))
->setClass('aphront-exception-dialog')
->setUser($viewer)
->appendChild($content);
if ($request->isAjax()) {
$dialog->addCancelButton('/', pht('Close'));
}
return id(new AphrontDialogResponse())
->setDialog($dialog)
->setHTTPResponseCode(500);
}
}
diff --git a/src/aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php b/src/aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php
index ff4ace2e4b..f8d522711f 100644
--- a/src/aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php
@@ -1,76 +1,76 @@
<?php
final class PhabricatorHighSecurityRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 310000;
}
public function getRequestExceptionHandlerDescription() {
return pht(
'Handles high security exceptions which occur when a user needs '.
'to present MFA credentials to take an action.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
if (!$this->isPhabricatorSite($request)) {
return false;
}
- return ($ex instanceof PhabricatorAuthHighSecurityRequiredException);
+ return ($throwable instanceof PhabricatorAuthHighSecurityRequiredException);
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$viewer = $this->getViewer($request);
$form = id(new PhabricatorAuthSessionEngine())->renderHighSecurityForm(
- $ex->getFactors(),
- $ex->getFactorValidationResults(),
+ $throwable->getFactors(),
+ $throwable->getFactorValidationResults(),
$viewer,
$request);
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht('Entering High Security'))
->setShortTitle(pht('Security Checkpoint'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->addHiddenInput(AphrontRequest::TYPE_HISEC, true)
->setErrors(
array(
pht(
'You are taking an action which requires you to enter '.
'high security.'),
))
->appendParagraph(
pht(
'High security mode helps protect your account from security '.
'threats, like session theft or someone messing with your stuff '.
'while you\'re grabbing a coffee. To enter high security mode, '.
'confirm your credentials.'))
->appendChild($form->buildLayoutView())
->appendParagraph(
pht(
'Your account will remain in high security mode for a short '.
'period of time. When you are finished taking sensitive '.
'actions, you should leave high security.'))
->setSubmitURI($request->getPath())
- ->addCancelButton($ex->getCancelURI())
+ ->addCancelButton($throwable->getCancelURI())
->addSubmitButton(pht('Enter High Security'));
$request_parameters = $request->getPassthroughRequestParameters(
$respect_quicksand = true);
foreach ($request_parameters as $key => $value) {
$dialog->addHiddenInput($key, $value);
}
return $dialog;
}
}
diff --git a/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php b/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php
index 1c84e90fd1..cb1dea3533 100644
--- a/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php
@@ -1,93 +1,95 @@
<?php
final class PhabricatorPolicyRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 320000;
}
public function getRequestExceptionHandlerDescription() {
return pht(
'Handles policy exceptions which occur when a user tries to '.
'do something they do not have permission to do.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
if (!$this->isPhabricatorSite($request)) {
return false;
}
- return ($ex instanceof PhabricatorPolicyException);
+ return ($throwable instanceof PhabricatorPolicyException);
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$viewer = $this->getViewer($request);
if (!$viewer->isLoggedIn()) {
// If the user isn't logged in, just give them a login form. This is
// probably a generally more useful response than a policy dialog that
// they have to click through to get a login form.
//
// Possibly we should add a header here like "you need to login to see
// the thing you are trying to look at".
$auth_app_class = 'PhabricatorAuthApplication';
$auth_app = PhabricatorApplication::getByClass($auth_app_class);
return id(new PhabricatorAuthStartController())
->setRequest($request)
->setCurrentApplication($auth_app)
->handleRequest($request);
}
$content = array(
phutil_tag(
'div',
array(
'class' => 'aphront-policy-rejection',
),
- $ex->getRejection()),
+ $throwable->getRejection()),
);
$list = null;
- if ($ex->getCapabilityName()) {
- $list = $ex->getMoreInfo();
+ if ($throwable->getCapabilityName()) {
+ $list = $throwable->getMoreInfo();
foreach ($list as $key => $item) {
$list[$key] = $item;
}
$content[] = phutil_tag(
'div',
array(
'class' => 'aphront-capability-details',
),
- pht('Users with the "%s" capability:', $ex->getCapabilityName()));
+ pht(
+ 'Users with the "%s" capability:',
+ $throwable->getCapabilityName()));
}
$dialog = id(new AphrontDialogView())
- ->setTitle($ex->getTitle())
+ ->setTitle($throwable->getTitle())
->setClass('aphront-access-dialog')
->setUser($viewer)
->appendChild($content);
if ($list) {
$dialog->appendList($list);
}
if ($request->isAjax()) {
$dialog->addCancelButton('/', pht('Close'));
} else {
$dialog->addCancelButton('/', pht('OK'));
}
return $dialog;
}
}
diff --git a/src/aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php b/src/aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php
index 3fb549c29f..78dad564b4 100644
--- a/src/aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php
+++ b/src/aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php
@@ -1,42 +1,42 @@
<?php
final class PhabricatorRateLimitRequestExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 300000;
}
public function getRequestExceptionHandlerDescription() {
return pht(
'Handles action rate limiting exceptions which occur when a user '.
'does something too frequently.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
if (!$this->isPhabricatorSite($request)) {
return false;
}
- return ($ex instanceof PhabricatorSystemActionRateLimitException);
+ return ($throwable instanceof PhabricatorSystemActionRateLimitException);
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$viewer = $this->getViewer($request);
return id(new AphrontDialogView())
->setTitle(pht('Slow Down!'))
->setUser($viewer)
->setErrors(array(pht('You are being rate limited.')))
- ->appendParagraph($ex->getMessage())
- ->appendParagraph($ex->getRateExplanation())
+ ->appendParagraph($throwable->getMessage())
+ ->appendParagraph($throwable->getRateExplanation())
->addCancelButton('/', pht('Okaaaaaaaaaaaaaay...'));
}
}
diff --git a/src/infrastructure/cluster/exception/PhabricatorClusterExceptionHandler.php b/src/infrastructure/cluster/exception/PhabricatorClusterExceptionHandler.php
index 2abda20b8f..ed0e0cc605 100644
--- a/src/infrastructure/cluster/exception/PhabricatorClusterExceptionHandler.php
+++ b/src/infrastructure/cluster/exception/PhabricatorClusterExceptionHandler.php
@@ -1,39 +1,39 @@
<?php
final class PhabricatorClusterExceptionHandler
extends PhabricatorRequestExceptionHandler {
public function getRequestExceptionHandlerPriority() {
return 300000;
}
public function getRequestExceptionHandlerDescription() {
return pht('Handles runtime problems with cluster configuration.');
}
- public function canHandleRequestException(
+ public function canHandleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
- return ($ex instanceof PhabricatorClusterException);
+ $throwable) {
+ return ($throwable instanceof PhabricatorClusterException);
}
- public function handleRequestException(
+ public function handleRequestThrowable(
AphrontRequest $request,
- Exception $ex) {
+ $throwable) {
$viewer = $this->getViewer($request);
- $title = $ex->getExceptionTitle();
+ $title = $throwable->getExceptionTitle();
$dialog = id(new AphrontDialogView())
->setTitle($title)
->setUser($viewer)
- ->appendParagraph($ex->getMessage())
+ ->appendParagraph($throwable->getMessage())
->addCancelButton('/', pht('Proceed With Caution'));
return id(new AphrontDialogResponse())
->setDialog($dialog)
->setHTTPResponseCode(500);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 8:58 AM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
186614
Default Alt Text
(39 KB)

Event Timeline