Parameters Lua:pcall的使用

Parameters Lua:pcall的使用,parameters,lua,try-catch,Parameters,Lua,Try Catch,我有一段Lua代码,它正在发送udp消息,正在工作。然而,我想让它更加防错。因此,我输入了错误的dns名称,导致解析失败。我真的不在乎块中的什么失败,我只想能够优雅地处理错误。在其他语言中,我会使用try-catch。在这里,我理解pcall应该填补这一空白。因此,我尝试使用pcall并尝试将buttonPin传递给sendMessageToServer()函数 此方法不起作用,未捕获任何内容,整个节点崩溃: if(pcall(sendMessageToServer, buttonPin)) t

我有一段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
dofile(“button.lua”)
按钮按下的启用销5。
等待按钮按下5。。。
按钮按下的启用销6。
正在等待6上的按钮按下。。。
>按下针脚5处的按钮。
通知服务器:36740
发送14695197份;5.按钮按哈希到服务器:36740
错误:无法发送消息。
按钮按下的启用销5。
等待按钮按下5。。。
DNS重试1!
DNS重试2!
DNS重试3!
DNS重试4次!
DNS失败!
ˆÈ)Š–F
ŽF
”Œ¦ú
NodeMCU 0.9.6构建20150704由Lua 5.1.4提供动力
按钮按下的启用销5。
等待按钮按下5。。。
按钮按下的启用销6。
正在等待6上的按钮按下。。。
IP不可用,正在等待。。。
>IP不可用,正在等待。。。
IP不可用,正在等待。。。
IP不可用,正在等待。。。
IP不可用,正在等待。。。
配置完成,IP为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...
配置完成,IP为192.168.x.x
按下针脚5处的按钮。
通知服务器:36740
发送14695197份;5.按钮按哈希到服务器:36740
消息已发送。
按钮按下的启用销5。
等待按钮按下5。。。

所以我不是手动发出错误信号。

您使用的是LuaSockets,对吗?您应该知道LuaSockets中的函数实际上不会引发错误。大多数函数,如,成功时返回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
当你说它在没有pcall的情况下工作时,你实际上是在愚弄自己。看起来你是这样做的:

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
块。

如果您表现出足够的尊重,至少正确键入语言名称,您将得到更多的响应。Lua不是首字母缩略词,大写L,仅此而已。卢阿。请解决此问题。您能否显示故意触发错误的stacktrace外观?错误是如何发出信号的?您使用的是
错误
/
lua\u错误
还是您的代码使用了一些“带外”的方式来表示lua不理解的错误?我已更新了我的原始问题,以包含更多的代码和错误消息。
pcall
只能捕获通过
错误
/
lua\u错误传播的错误。据我所知,您看到的这些错误只是被输出到stderr。您正在使用的API如何传达错误?你需要用上面提到的函数将它们作为lua错误重新显示。这个问题本身有问题。您不能简单地将pcall的代码包装到
function()。。。结束
并获得不同的行为。