Why Try/Catch doesn't work in phpredis connect function?
Asked Answered
T

4

8

I am using redis as a caching store through phpredis. It works perfectly and I want to provide some fail-safe way to make sure the caching feature is always up (using file-based caching, for example), even when redis server goes down, initially I came up with the following code

<?php
    $redis=new Redis();
    try {
        $redis->connect('127.0.0.1', 6379);
    } catch (Exception $e) {
        // tried changing to RedisException, didn't work either
        // insert codes that'll deal with situations when connection to the redis server is not good
        die( "Cannot connect to redis server:".$e->getMessage() );
    }
    $redis->setex('somekey', 60, 'some value');

But when redis server is down, I got

    PHP Fatal error:  Uncaught exception 'RedisException' with message 'Redis server went away' in /var/www/2.php:10
Stack trace:
#0 /var/www/2.php(10): Redis->setex('somekey', 60, 'some value')
#1 {main}
  thrown in /var/www/2.php on line 10

The code the catch block didn't get executed. I went back to read the phpredis doc and came up with the following solution instead

<?php
    $redis=new Redis();
    $connected= $redis->connect('127.0.0.1', 6379);
    if(!$connected) {
        // some other code to handle connection problem
        die( "Cannot connect to redis server.\n" );
    }
    $redis->setex('somekey', 60, 'some value');

I can live with that but my curiosity would never get satisfied so here comes my question: why the try/catch method doesn't work with the connection error?

Tertia answered 26/3, 2012 at 23:1 Comment(2)
$redis->connect(); does not throw a an exception if a connection simply fails. What you can do is check if $redis===true, if it is true then you are connected, otherwise you are not connected. But as Nicolas notes below, the exception above is from setex, therefore it will not be catched unless you put it within the try catch block.Nancienancy
@haluk Redis connect method throws an exception.Huge
D
4

Your exception was sent from setex, which is outside of the try {} block. Put the setex inside the try block and the exception will be caught.

Dagnydago answered 27/3, 2012 at 9:2 Comment(2)
I think he is expecting to catch an exception regarding the service not being available, along with the one for a malformed command.Dagan
@Niloct, you read my mind :D Indeed it would be nice if exception can be caught while calling connect().Tertia
N
2

As Nicolas said, the exception comes from setex, but you can avoid that (and even the try/catch block) by using the ping command:

$redis=new Redis();
$redis->connect('127.0.0.1', 6379);

if(!$redis->ping())
{
    die( "Cannot connect to redis server.\n" );
}

$redis->setex('somekey', 60, 'some value');
Nierman answered 28/3, 2012 at 18:29 Comment(1)
Thanks for your answer but I don't see why using an extra command (ping in your answer) is better than just checking for the result from connect(), which is what I am actually using in my code.Tertia
T
0

It will able to catch connection exception if you catch '\Predis\Connection\ConnectionException'.

Or you can use \Exception instead of Exception (Notice the forward slash in front).

Typhoid answered 24/4, 2019 at 8:6 Comment(1)
This is incorrect. The exception you mention, \Predis\Connection\ConnectionException, is thrown by the Predis client, not phpredis.Dagnydago
V
0

I had the same issue and I was able to find the solution here at https://github.com/phpredis/phpredis/issues/1641

<?php
$obj_r = new Redis();

$port = isset($argv[1]) ? $argv[1] : 6379;
echo "Attempting to connect to port $port: ";

try {
    $obj_r->connect('127.0.0.1', $port);
} catch(RedisException $ex) {
    $m = $ex->getMessage();
    echo "ERROR ($m)\n";
}

if ($obj_r->isConnected()) {
    echo "OK\n";
    echo "PING -> " . $obj_r->ping() . "\n";
} else {
    // some other code to handle connection problem
    echo "Not connected, can't send PING!\n";
}
?>
Vardon answered 26/5, 2022 at 17:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.