我有一段Lua代码正在发送udp消息,这是有效的。但是我想让它更加错误证明。所以我输入了一个错误的DNS名称来引发解决方案失败。我真的不在乎该块中的失败,我只是希望能够优雅地处理错误。在其他语言中,我会使用try-catch。在这里,我理解pcall
应该填补这个空白。所以我正在尝试使用pcall并尝试将buttonPin
传递给sendMessageToServer()
函数。
这种方法不起作用,没有捕获任何内容,整个节点崩溃:
if(pcall(sendMessageToServer, buttonPin))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
这种做法恰恰相反:它没有崩溃,看起来好像一切都好,所以pcall
返回true:
if(pcall(function() sendMessageToServer(buttonPin) end))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
但它应该运行...如果我只是删除单词pcall
,使该函数定期运行,则崩溃按预期发生。
祝你好运, 延
更新:完整代码并故意导致错误
require ("config")
require ("cryptography")
function armAllButtons()
ledOff(ledGreen)
ledOff(ledYellow)
ledOff(ledRed)
for i,v in ipairs(buttonPins)
do
--print(i,v)
armButton(v)
end
end
function armButton(buttonPin)
print("Arming pin "..buttonPin.." for button presses.")
gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
gpio.trig(buttonPin, direction, function () notifyButtonPressed(buttonPin) end)
print("Waiting for button press on "..buttonPin.."...")
end
function notifyButtonPressed(buttonPin)
--print("Button pressed. Notifiying server at "..serverIp..":"..serverPort)
-- show status
ledOn(ledYellow)
print("Button at pin "..buttonPin.." pressed.")
ledOff(ledGreen)
ledOff(ledYellow)
ledOff(ledRed)
-- show status
--if(pcall(sendMessageToServer,buttonPin))
if(sendMessageToServer(buttonPin))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
-- Rearm pin for interrupts
armButton(buttonPin)
end
function sendMessageToServer(buttonPin)
print("Notifying server at "..serverIp..":"..serverPort)
--TODO: Include some variable. The current code is vulnerable to replay attacks.
conn = net.createConnection(net.UDP, 0)
conn:connect(serverPort,serverIp)
local msg = node.chipid()..";"..buttonPin..";ButtonPressed"
local hash = getHashValue(msg..encryptionPassword)
print("Sending "..msg.." with hash "..hash.." to server "..serverIp..":"..serverPort)
conn:send(msg..';'..hash)
conn:close()
conn = nil
end
function ledOn(ledPin)
gpio.write(ledPin,gpio.HIGH)
end
function ledOff(ledPin)
gpio.write(ledPin,gpio.LOW)
end
armAllButtons()
不使用pcall时出错:
dofile("button.lua")
Arming pin 5 for button presses.
Waiting for button press on 5...
Arming pin 6 for button presses.
Waiting for button press on 6...
> Button at pin 5 pressed.
Notifying server at <incorrectDnsEntry>:36740
Sending 14695197;5;ButtonPressed with hash <someHashValue> to server <incorrectDnsEntry>:36740
Error: Message could not be sent.
Arming pin 5 for button presses.
Waiting for button press on 5...
DNS retry 1!
DNS retry 2!
DNS retry 3!
DNS retry 4!
DNS Fail!
?ˆÈ)ŠâF
‘ŽF
”Œ¦ú
NodeMCU 0.9.6 build 20150704 powered by Lua 5.1.4
Arming pin 5 for button presses.
Waiting for button press on 5...
Arming pin 6 for button presses.
Waiting for button press on 6...
IP unavaiable, Waiting...
> IP unavaiable, Waiting...
IP unavaiable, Waiting...
IP unavaiable, Waiting...
IP unavaiable, Waiting...
Config done, IP is 192.168.x.x
使用pcall显示:
Config done, IP is 192.168.x.x
Button at pin 5 pressed.
Notifying server at <incorrectDnsEntry>:36740
Sending 14695197;5;ButtonPressed with hash <someHashValue> to server <incorrectDnsEntry>:36740
Message sent.
Arming pin 5 for button presses.
Waiting for button press on 5...
所以我没有手动发出错误信号。
答案 0 :(得分:0)
你正在使用LuaSockets吗?您应该知道LuaSockets中的函数实际上不会引发错误。大多数函数,如udp send,在成功时返回1,在出现错误时返回nil + msg。如果要引发错误,则需要检查返回值并自行引发错误。一种非常常见的方法是将调用包装在一个断言中,如下所示:
assert(conn:send(msg..';'..hash))
如果你说它没有电脑就可以工作那么你实在在欺骗自己。看起来好像你这样做:
if(sendMessageToServer(buttonPin))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
以上代码将始终打印“错误:无法发送消息”。因为sendMessageToServer
函数永远不会返回任何内容,在这种情况下,if条件将始终评估为false,并且无论您是否设法发送数据,都将在else
块中结束。