Fix sentinel discovery methods not catching StreamInitException (#1650)

* Fix sentinel discovery methods not catching StreamInitException

The getMaster(), getSlaves(), and updateSentinels() methods only catch
ConnectionException when connecting to Sentinel nodes. StreamInitException
(thrown by stream_socket_client() failures) extends PredisException directly,
not ConnectionException, so it propagates uncaught — preventing fallback to
the next Sentinel node.

This causes complete application failure when any single Sentinel is
unreachable, even if other Sentinels are healthy.

Add StreamInitException to the catch clause using a union type in all three
methods. This is more precise than catching PredisException, which would
also swallow ServerException (e.g. "ERR No such master with that name")
and mask configuration errors.

See also #1577 which applied a similar fix to retryCommandOnFailure().

* Fix coding standards and add changelog entry

- Remove spaces around | in union catch (php-cs-fixer)
- Add CHANGELOG.md entry for #1650

* Codestlye fixes

---------

Co-authored-by: Wolfgang Kerschbaumer <wolfgang.kerschbaumer@bergfex.at>
Co-authored-by: vladvildanov <vladyslav.vildanov@redis.com>
This commit is contained in:
Wolfgang Kerschbaumer
2026-03-05 16:01:40 +01:00
committed by GitHub
parent 274cb866bd
commit d0f6671a60
2 changed files with 5 additions and 3 deletions
+1
View File
@@ -1,6 +1,7 @@
## Changelog
## Unreleased
- Fixed Sentinel getParameters() executed on string configuration (#1649)
- Fixed Sentinel discovery methods not catching `StreamInitException` on connection failure (#1650)
## v3.4.1 (2026-02-23)
### Added
@@ -24,6 +24,7 @@ use Predis\Connection\NodeConnectionInterface;
use Predis\Connection\Parameters;
use Predis\Connection\ParametersInterface;
use Predis\Connection\RelayFactory;
use Predis\Connection\Resource\Exception\StreamInitException;
use Predis\Replication\ReplicationStrategy;
use Predis\Replication\RoleException;
use Predis\Response\Error;
@@ -346,7 +347,7 @@ class SentinelReplication extends AbstractAggregateConnection implements Replica
'role' => 'sentinel',
];
}
} catch (ConnectionException $exception) {
} catch (ConnectionException|StreamInitException $exception) {
$this->sentinelConnection = null;
goto SENTINEL_QUERY;
@@ -480,7 +481,7 @@ class SentinelReplication extends AbstractAggregateConnection implements Replica
$masterConnection = $this->connectionFactory->create($masterParameters);
$this->add($masterConnection);
} catch (ConnectionException $exception) {
} catch (ConnectionException|StreamInitException $exception) {
$this->sentinelConnection = null;
goto SENTINEL_QUERY;
@@ -512,7 +513,7 @@ class SentinelReplication extends AbstractAggregateConnection implements Replica
foreach ($slavesParameters as $slaveParameters) {
$this->add($this->connectionFactory->create($slaveParameters));
}
} catch (ConnectionException $exception) {
} catch (ConnectionException|StreamInitException $exception) {
$this->sentinelConnection = null;
goto SENTINEL_QUERY;