1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52: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:
epriestley 2018-05-17 05:56:43 -07:00
parent 8f9b948447
commit 3c5668b4a5
2 changed files with 28 additions and 8 deletions

View file

@ -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();

View file

@ -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(
'Unable to establish a connection to any database host '.
'(while trying "%s"). All masters and replicas are completely '.
'unreachable.',
$database));
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);
if ($proxy) {
$proxy_message = pht(
'%s: %s',
get_class($proxy),
$proxy->getMessage());
$message = $message."\n\n".$proxy_message;
}
throw new PhabricatorClusterStrandedException($message);
}