sewenew / redis-plus-plus

Redis client written in C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue with Specific Redis Plus Plus Exceptions Not Being Caught

Hamza091 opened this issue · comments

Hi, I'm currently facing an issue while using async redis plus plus, specifically related to handling exceptions. I've implemented the usage of future objects to retrieve values in callbacks. However, I've encountered an unexpected behavior where specific Redis Plus Plus exceptions, such as ClosedError or IoError, are not being caught as expected. Instead, a generic Error exception is consistently thrown. Here's the code snippet:

void readMsgCallBack(Future<Streams>&&fut){
   Streams reply;
    try{

        reply = fut.get();
        
    }catch(const ClosedError &err){
        cout<<"ClosedError "<<endl;
        cout<<string(err.what())<<endl;
    }catch(const IoError &err){
        cout<<"IoError "<<endl;
        cout<<string(err.what())<<endl;
    }catch(const Error &err){
        cout<<"Error "<<endl;
        cout<<string(err.what())<<endl;
    } 
}

What could be the possible reason for this behaviour?

Sorry, but I cannot reproduce your problem. You can try the following code:

AsyncRedis r("redis://127.0.0.1:6378");   // <---- set a wrong port number, and the client will get an IO error.
r.get("key", [](Future<OptionalString> &&fut) {
            try {
                cout << *fut.get() << endl;
            } catch (const ClosedError &e) {
                cout << "closed error: " << e.what() << endl;
            } catch (const IoError &e) {
                cout << "io error: " << e.what() << endl;
            } catch (const Error &e) {
                cout << "error: " << e.what() << endl;
            }
        });
string s;
cin >> s;

Since Redis does not listen on port 6378, the client receives a IO error, and it print io error: xxxxxx.

It seems that you might not get any IO error. You can check the error message to see if it's really an IO error.

Regards

Thank you for the code snippet. I've tried it out, and indeed, setting the wrong port number results in an IO error as expected. I think the problem is specifically with the generic command interface for async redis. Could you please verify this? because I am still getting same issue with generic command interface.

This has nothing to do with generic interface, and you can change the get command with a generic interface call to test it:

AsyncRedis r("redis://127.0.0.1:6378");   // <---- set a wrong port number, and the client will get an IO error.
r.command<OptionalString>("get", "key", [](Future<OptionalString> &&fut) {    // <---- call `get` with generic interface
            try {
                cout << *fut.get() << endl;
            } catch (const ClosedError &e) {
                cout << "closed error: " << e.what() << endl;
            } catch (const IoError &e) {
                cout << "io error: " << e.what() << endl;
            } catch (const Error &e) {
                cout << "error: " << e.what() << endl;
            }
        });
string s;
cin >> s;

And it shows the same result.

Maybe you can show me a minimum code snippet that reproducing your problem, so that I can do some research on it.

Regards

Actually, I want to handle failover conditions and want to do retries based on specific exceptions, like if connection is lost during execution of some query or if there is some network issue then I intend to rerun that query. Specifically, if I execute a blocking query and encounter a connection closure while Redis is stopped, I anticipate a ClosedError exception. While this scenario functions correctly with synchronous Redis, I'm encountering difficulties in capturing these specific exceptions with asynchronous Redis.

Code snippet to reproduce the issue:

vector<string> command =  {"XREADGROUP","GROUP",groupName,consumerName,"BLOCK","0","COUNT","1","STREAMS",topic,">"};

asyncRedis->command<Streams>(command.begin(),command.end(),[callBack](Future<Streams> &&fut){

            std::exception* exp = nullptr;
            Streams res;
            
            try{
                res = fut.get();

            }catch(ClosedError &err){

                // connection is closed during execution of some query     
                cout<<string(err.what())<<endl;
                // do retries
         

            }catch(IoError &err){

                // connection refused
                cout<<string(err.what())<<endl;
                // do retries
          

            }catch(Error &err){

                cout<<string(err.what())<<endl;
               
            }      
                
        });
`

Thanks for describing your scenario, and I can reproduce your problem with any blocking command, such as BLPOP.

I've fixed the problem, and you can try the latest code. If you still have problem, feel free to let me know.

Regards

Close the issue, since there's no update.

Regards