mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
When database connection exceptions occur, raise them to the setup layer
Summary: Ref T13141. Currently, during first-time setup we don't surface all the details about connection exceptions that we could: the underlying exception is discarded inside cluster connection management. This isn't a huge issue since the reason for connection problems is usually fairly obvious, but in at least one case (see T13141) we hit a less-than-obvious exception. Instead, store the original exception and propagate the message up the stack so users have more information about the problem. Test Plan: - Configured an intentionally bad MySQL username. - Restarted Apache and loaded Phabricator. - Got a more helpful exception with a specific authentication error message. {F5622361} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13141 Differential Revision: https://secure.phabricator.com/D19454
This commit is contained in:
parent
8f9b948447
commit
3c5668b4a5
2 changed files with 28 additions and 8 deletions
|
@ -29,6 +29,7 @@ final class PhabricatorDatabaseRef
|
|||
private $connectionLatency;
|
||||
private $connectionStatus;
|
||||
private $connectionMessage;
|
||||
private $connectionException;
|
||||
|
||||
private $replicaStatus;
|
||||
private $replicaMessage;
|
||||
|
@ -453,6 +454,7 @@ final class PhabricatorDatabaseRef
|
|||
return false;
|
||||
}
|
||||
|
||||
$this->connectionException = null;
|
||||
try {
|
||||
$connection->openConnection();
|
||||
$reachable = true;
|
||||
|
@ -463,6 +465,7 @@ final class PhabricatorDatabaseRef
|
|||
// yet.
|
||||
throw $ex;
|
||||
} catch (Exception $ex) {
|
||||
$this->connectionException = $ex;
|
||||
$reachable = false;
|
||||
}
|
||||
|
||||
|
@ -506,6 +509,10 @@ final class PhabricatorDatabaseRef
|
|||
return $this->healthRecord;
|
||||
}
|
||||
|
||||
public function getConnectionException() {
|
||||
return $this->connectionException;
|
||||
}
|
||||
|
||||
public static function getActiveDatabaseRefs() {
|
||||
$refs = array();
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
|||
$master = PhabricatorDatabaseRef::getMasterDatabaseRefForApplication(
|
||||
$application);
|
||||
|
||||
$master_exception = null;
|
||||
|
||||
if ($master && !$master->isSevered()) {
|
||||
$connection = $master->newApplicationConnection($database);
|
||||
if ($master->isReachable($connection)) {
|
||||
|
@ -91,6 +93,8 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
|||
PhabricatorEnv::setReadOnly(
|
||||
true,
|
||||
PhabricatorEnv::READONLY_UNREACHABLE);
|
||||
|
||||
$master_exception = $master->getConnectionException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +112,7 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
|||
$this->raiseUnconfigured($database);
|
||||
}
|
||||
|
||||
$this->raiseUnreachable($database);
|
||||
$this->raiseUnreachable($database, $master_exception);
|
||||
}
|
||||
|
||||
private function raiseImproperWrite($database) {
|
||||
|
@ -136,13 +140,22 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
|||
$database));
|
||||
}
|
||||
|
||||
private function raiseUnreachable($database) {
|
||||
throw new PhabricatorClusterStrandedException(
|
||||
pht(
|
||||
private function raiseUnreachable($database, Exception $proxy = null) {
|
||||
$message = pht(
|
||||
'Unable to establish a connection to any database host '.
|
||||
'(while trying "%s"). All masters and replicas are completely '.
|
||||
'unreachable.',
|
||||
$database));
|
||||
$database);
|
||||
|
||||
if ($proxy) {
|
||||
$proxy_message = pht(
|
||||
'%s: %s',
|
||||
get_class($proxy),
|
||||
$proxy->getMessage());
|
||||
$message = $message."\n\n".$proxy_message;
|
||||
}
|
||||
|
||||
throw new PhabricatorClusterStrandedException($message);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue