2013-12-18 109 views
4

我試圖執行以下錯誤eval命令理解redis.call()和redis.pcall()舉例說明本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的文檔所示.CA ll()與redis.pcall()類似,唯一的區別是,如果Redis命令調用會導致錯誤,則redis.call()將引發Lua錯誤,從而強制EVAL將錯誤返回給命令調用者,而redis.pcall將捕獲返回代表錯誤的Lua表的錯誤。「

所以根據文檔,在使用redis.pcall()的情況下,錯誤應該被困住了,對!在那種情況下,爲什麼兩個錯誤都是相同的?如果我誤解了差異,如果有人能夠清楚地說明命令之間的區別,那將會更好!

回答

9

這是因爲在你示例命令不產生錯誤,使用的是redis.callredis.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" 
+0

很好的指導答案! –

2

由於Redis無法執行調用或pcall命令,所以失敗。我的意思是在實際的Redis命令(這裏是一個get命令)執行之前它失敗了。 pcall將在執行Redis命令期間捕獲錯誤,而不是在執行pcall本身期間發生錯誤。

讓我們修改您的輸入以使Redis命令失敗(而不是redis.call命令本身)。

> EVAL "return redis.call(ARGV[1],KEYS[1])" 1 key get 
"100" 

> EVAL "return redis.call(ARGV[1],KEYS[1])" 1 key born_to_fail 
(error) ERR Error running script (call to f_2673dc91ae540aa65dedd262a952d5338e330b37): @user_script:1: @user_script: 1: Unknown Redis command called from Lua script 

> EVAL "return redis.pcall(ARGV[1],KEYS[1])" 1 key born_to_fail 
(error) @user_script: 1: Unknown Redis command called from Lua script 

您可以在第二次調用中看到Redis錯誤導致Lua錯誤。

在第三次調用時,使用pcall代替,所以結果不再是Lua錯誤,而只是包含錯誤文本的輸出字符串。

+1

我們的反應之間的競爭條件:) – catwell

+0

是的......你的是更完整的! –

相關問題