Description
Symfony version(s) affected
7.2.0
Description
Hi,
When updating our 7.1.x application to 7.2.0 we've experienced a regression on the Lock component in a specific configuration using predis/predis.
It seems that the newly introduced evalSha
approach (#58533) is not working when using Lock component with both predis and Cache component.
Predis\Client
has an option to throw or not exceptions when receiving errors from Redis (see \Predis\Client::onErrorResponse) but this seems to be forced to false
by Symfony\Component\Cache\Adapter\RedisAdapter
Due to this behavior, the logic introduced to Symfony\Component\Lock\Store\RedisStore
in #58533 for Predis can't work properly because no ServerException
are thrown. Instead, $this->redis->evalSha()
calls return a Predis\Response\Error
containing the expected error message (self::NO_SCRIPT_ERROR_MESSAGE
) when the script hasn't been loaded yet :
try {
return $this->redis->evalSha($scriptSha, 1, $resource, ...$args);
} catch (ServerException $e) {
// Fallthrough only if we need to load the script
if (self::NO_SCRIPT_ERROR_MESSAGE !== $e->getMessage()) {
throw new LockStorageException($e->getMessage(), $e->getCode(), $e);
}
}
try {
$this->redis->script('LOAD', $script);
} catch (ServerException $e) {
throw new LockStorageException($e->getMessage(), $e->getCode(), $e);
}
try {
return $this->redis->evalSha($scriptSha, 1, $resource, ...$args);
} catch (ServerException $e) {
throw new LockStorageException($e->getMessage(), $e->getCode(), $e);
}
How to reproduce
- Clone https://github.com/Yondz/symfony_bug_lock_7.2 and install dependencies
- Make sure you don't have php8.x-redis extension enabled to ensure
predis
usage - Start the redis container :
docker compose up -d
- Launch this command (wrapped by
symfony
cli) :symfony console app:lock:issue
Possible Solution
I guess RedisStore
could be fixed to test if $this->redis->getOptions()->exceptions
is true
(then try/catch is applicable) or false
(then result response should be manipulated)
A simple workaround would be to manually throw ServerException
if the evalSha
returns an Error
, but this will have to be handled in the 3 try/catches
Additional Context
No response