From f939e3bbdc23696f7321c022214d7c7111d915cf Mon Sep 17 00:00:00 2001 From: Dan Barker Date: Wed, 9 Apr 2025 10:40:57 +0100 Subject: [PATCH] Add retry mechanism and more detailed logging for PDOException/AdapterException in ConnectionFactory --- src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php | 6 ++ .../Runtime/Connection/ConnectionFactory.php | 63 +++++++++++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php b/src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php index bf1a99d2e5..55aa511e09 100644 --- a/src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php +++ b/src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php @@ -79,6 +79,12 @@ public function getConnection(array $params): PdoConnection $con = new PdoConnection($dsn, $user, $password, $driverOptions); $this->initConnection($con, isset($params['settings']) && is_array($params['settings']) ? $params['settings'] : []); } catch (PDOException $e) { + // Detailed error logging + error_log(sprintf('PDO Connection Error: DSN: %s, Error: %s, Code: %s', + preg_replace('/password=.*?;/', 'password=***;', $dsn), + $e->getMessage(), + $e->getCode() + )); throw new AdapterException('Unable to open PDO connection', 0, $e); } diff --git a/src/Propel/Runtime/Connection/ConnectionFactory.php b/src/Propel/Runtime/Connection/ConnectionFactory.php index 7319719ad4..b7cb116df9 100644 --- a/src/Propel/Runtime/Connection/ConnectionFactory.php +++ b/src/Propel/Runtime/Connection/ConnectionFactory.php @@ -51,28 +51,53 @@ public static function create( } else { $connectionClass = $defaultConnectionClass; } - try { - $adapterConnection = $adapter->getConnection($configuration); - } catch (AdapterException $e) { - throw new ConnectionException('Unable to open connection', 0, $e); - } - /** @var \Propel\Runtime\Connection\ConnectionInterface $connection */ - $connection = new $connectionClass($adapterConnection); - - // load any connection options from the config file - // connection attributes are those PDO flags that have to be set on the initialized connection - if (isset($configuration['attributes']) && is_array($configuration['attributes'])) { - foreach ($configuration['attributes'] as $option => $value) { - if (is_string($value) && strpos($value, '::') !== false) { - if (!defined($value)) { - throw new InvalidArgumentException(sprintf('Invalid class constant specified "%s" while processing connection attributes for datasource "%s"', $value, $connection->getName())); + + $maxRetries = 2; + $retryCount = 0; + $lastException = null; + + while ($retryCount <= $maxRetries) { + try { + $adapterConnection = $adapter->getConnection($configuration); + + /** @var \Propel\Runtime\Connection\ConnectionInterface $connection */ + $connection = new $connectionClass($adapterConnection); + + // load any connection options from the config file + // connection attributes are those PDO flags that have to be set on the initialized connection + if (isset($configuration['attributes']) && is_array($configuration['attributes'])) { + foreach ($configuration['attributes'] as $option => $value) { + if (is_string($value) && strpos($value, '::') !== false) { + if (!defined($value)) { + throw new InvalidArgumentException(sprintf('Invalid class constant specified "%s" while processing connection attributes for datasource "%s"', $value, $connection->getName())); + } + $value = constant($value); + } + $connection->setAttribute($option, $value); } - $value = constant($value); } - $connection->setAttribute($option, $value); + + return $connection; + + } catch (AdapterException $e) { + $lastException = $e; + $retryCount++; + + // Log the connection attempt failure + error_log(sprintf('Propel connection attempt %d/%d failed: %s', + $retryCount, + $maxRetries + 1, + $e->getMessage() . ' - ' . ($e->getPrevious() ? $e->getPrevious()->getMessage() : '') + )); + + if ($retryCount <= $maxRetries) { + // Wait before retrying + usleep(100000); // 100ms + } } } - - return $connection; + + // If we get here, all retries have failed + throw new ConnectionException('Unable to open connection after ' . ($maxRetries + 1) . ' attempts', 0, $lastException); } }