Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Specific Redis Plus Plus Exceptions Not Being Caught #545

Closed
Hamza091 opened this issue Feb 2, 2024 · 6 comments
Closed

Issue with Specific Redis Plus Plus Exceptions Not Being Caught #545

Hamza091 opened this issue Feb 2, 2024 · 6 comments

Comments

@Hamza091
Copy link

Hamza091 commented Feb 2, 2024

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?

@sewenew
Copy link
Owner

sewenew commented Feb 8, 2024

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

@Hamza091
Copy link
Author

Hamza091 commented Feb 8, 2024

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.

@sewenew
Copy link
Owner

sewenew commented Feb 8, 2024

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

@Hamza091
Copy link
Author

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;
               
            }      
                
        });
`

@sewenew
Copy link
Owner

sewenew commented Feb 11, 2024

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

@sewenew
Copy link
Owner

sewenew commented Feb 18, 2024

Close the issue, since there's no update.

Regards

@sewenew sewenew closed this as completed Feb 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants