我尝试执行以下错误的eval命令来理解redis.call()和redis.pcall()之间的区别
eval "return redis.call(ARGV[2],KEYS[1])" 1 key get eval "return redis.pcall(ARGV[2],KEYS[1])" 1 key get
在这两种情况下,我都得到了以下错误,
(error) Lua redis() command arguments must be strings or integers
此错误不会传达redis.call()和redis.pcall()之间的区别,如文档所示
"redis.call()类似于redis.pcall(),唯一的区别是如果Redis命令调用将导致错误,redis.call()将引发Lua错误,反过来将强制EVAL返回命令调用程序出错,而redis.pcall将捕获错误,返回表示错误的Lua表."
所以根据文档,在使用redis.pcall()的情况下,错误应该被困,对吧!在那种情况下为什么两个错误都相同?如果我误解了差异,那么如果有人能够清楚地说明命令之间的区别,那就更好了!!
这是一个棘手的情况,因为在你示例命令不产生错误,使用的是redis.call
与redis.pcall
不正确地(因为ARGV[2]
是nil
像该错误消息是告诉你).因此在这两种情况下都不会恢复错误.
以下是命令实际失败的示例,您可以看到差异:
redis 127.0.0.1:6379> set foo bar OK redis 127.0.0.1:6379> eval 'redis.call("hget","foo","bar")' 0 (error) ERR Error running script (call to f_9e6d82f0740926e0a70775430bda59a54d4e0664): ERR Operation against a key holding the wrong kind of value redis 127.0.0.1:6379> eval 'redis.pcall("hget","foo","bar")' 0 (nil)
但是,您可能会注意到我没有返回结果pcall
,因此脚本返回nil
.如果我返回错误命令的结果怎么办?
redis 127.0.0.1:6379> eval 'return redis.call("hget","foo","bar")' 0 (error) ERR Error running script (call to f_d0a8dce7264708876edf262052788fc90a8e8325): ERR Operation against a key holding the wrong kind of value redis 127.0.0.1:6379> eval 'return redis.pcall("hget","foo","bar")' 0 (error) ERR Operation against a key holding the wrong kind of value
有了call
什么变化,因为错误(认为它像其他语言的异常-使用Java,Python等)被抛出的函数有机会返回反正之前.
随着pcall
虽然,函数调用会返回一个表err
字段,被转换为一个"错误回答"通过Redis的,所以你看不到它.你怎么检查?线性化它!
redis 127.0.0.1:6379> eval 'local t = redis.pcall("hget","foo","bar"); local r = {type(t)}; for k,v in pairs(t) do r[#r+1] = k; r[#r+1] = v; end; return r' 0 1) "table" 2) "err" 3) "ERR Operation against a key holding the wrong kind of value"