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
MULTI EXEC will not return error when some of the commands fails #689
Comments
@bitinn good find and research on this! In terms of diverging on the hiredis parser, most likely we'd need to pair this with a pull request for that library as well. I'm not as concerned about that for a few reasons: 1. the javascript parser is better in most cases these days, and 2. it won't even work with Node 0.11 or 0.12 without its own major work. As for fixing this library going forward (in the case where we disregard hiredis for now) I think the first step is to create a canonical set of test cases and output so we can decide we have a sufficient mechanism for deducing these errors. Hopefully that's not going through Redis source to collect all the error messages, but it may come to that. |
@brycebaril I don't fully understand why redis-server can't reply like:
but instead of use
At least that's what the protocol document are suggesting? UPDATE: ah, because some commands doesn't reply with simple string, silly me... hopefully redis-server stick to a certain way of encoding responses as bulk strings, so we can use a subroutine to parse and decode them. |
I ran into the same problem and was about to file an issue when i saw this one. Semi-related: |
For now the best advice I can offer is don't have this problem. It's lame, I know, but one nice thing about Redis is the only errors are operations that should be avoidable, e.g. bad command syntax or mismatching commands and types. Any time you do get an Error from Redis should likely be considered a bug in your use of Redis, and an invalid application. Of course that isn't the long-term solution because we need our applications to be robust in the face of uncertainty. Beyond that it's going to require working around this quirk in the Redis protocol and inspecting the replies. |
Thanks for the reply @brycebaril! I understand what you are saying, that most errors are developer errors. The case I was specifically looking at was a disconnect. If our Redis goes down 500 server errors are to be expected (we have a reconnect in place) but the errors should be clear/logged/tracable. If it's an array of errors this might not be the case, nor if the error is not exposed as an error but a normal result string... I hope it will be rare but because an error case is so rare you want to have the right logging/information when it happens. |
Found some useful docs on this which confirm it is expected behaviour, might help others:
M |
In order to better support this project and its new group of collaborators under a new org we are trying to clean up and close issues older than 6 months. Your issue may have been fixed since the issue was open, however, if you are still experiencing a problem please re-open this issue and we will label it accordingly. |
@blainsmith It's a known issue for redis clients, please look into it when available. I would love to see how you handle this in general.
|
@bitinn What would you say the client should do? Some thoughts:
In https://github.com/gosquared/redis-clustr, I handle this by keeping an array of errors and another of responses and simply callback with both. For example: var multi = redis.multi();
multi.get('test', function(err, value) { }); // pretend this errors
multi.get('test2', function(err, value) { }); // and this succeeds
multi.exec(function(errs, resp) {
// errs = [ Error ]
// resp = [ undefined, value ]
}); This isn't a great way of handling it (you can't see what commands errored easily), and individual command callbacks are much better. My personal opinion is that errors within the exec callback should be var multi = redis.multi();
multi.get('test', function(err, value) { /* errors should be handled here */ });
multi.get('test2', function(err, value) { /* ... */ });
multi.exec(function(err, resp) {
// err = null
// resp = [ Error || value, Error || value ... ]
}); Not got terribly strong opinions on this though so would love to hear ideas! |
I think I prefer introducing a new error type, say I haven't looked into this since, so I am not sure whether this is possible with current node_redis parser. |
Looping in @dohse, who has submitted a partial solution to this problem. I like the simplicity of this solution, but I agree with concerns that it's a bit strange that errors and good responses are intermixed. This might be the best solution in the short term, however, since I think switching to returning an error in the errback would require a major semver bump? |
@bitinn does this apply to the the js parser and the hiredis parser or only to the js one? |
@BridgeAR I would say both, but I haven't been using the hiredis parser lately. This comment suggests hiredis is affected, but return slightly different results: |
@bitinn the different behavior is already fixed on master. As I played around with multi is seems like it's really behaving very inconsistent. The error is going to land in either the result or the error value depending on what kind of error is thrown. But if the command itself is malformed e.g. client.config('abc'); it'll result in: The individual command callback in multi behaves just the same. So the error is misplaces just the same. I suggest to fix this as follows:
That way it's possible to check if and what error occurred without the need to go through an array of errors and check each individually. What do you all think? |
Sounds good to me! I am happy as long as the |
@bitinn I gave this another thought and decided not to break node style err / reply behavior. So the new behavior will be like this:
I hope that'll be a good outcome for you. |
@BridgeAR Thx for your work and yes it's a major improvement over what we had. |
I don't think reject gets called.
is thrown instead. Is there no way around that? |
It took me a long time to figure out why: when some of queued commands fail to execute, Redis server send reply as Bulk Strings, and in both node_redis javascript parser and hiredis wrapper, they are emitted as
reply
, notreply error
.Thus in exec callback,
err
will be null,res
will be an array containing all replies, both ok and error. eg.(note the errors are returned as string, not wrapped in
Error
, so no easy way to determine whether MULTI EXEC are run successfully)I am not sure the best way to fix this, changing how node_redis parser handle this type of responses will probably cause it to diverge with hiredis behaviour...
But at the very least we should document it, so issues don't come up again and again, like #624 & #550.
What do you guys think? @brycebaril @mranney @mocheng @bsnote @guileen (apologize for the mass notice if you are not interested)
Reference:
The text was updated successfully, but these errors were encountered: