I have a piece of Lua code that is sending a udp message out, that is working. However I want to make it more error proof. So I have entered a wrong dns name to provoke a resolution failure. I do not really care what in that block fails, I just want to be able to handle the error gracefully. In other languages I would use try-catch. Here I understand pcall
is supposed to fill that gap. So I am trying to use pcall and am trying to pass buttonPin
to the sendMessageToServer()
function.
This approach is not working, nothing is caught, the whole node crashes:
if(pcall(sendMessageToServer, buttonPin))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
This approach does the opposite: It doesn't crash and looks as if everything is ok, so pcall
returns true:
if(pcall(function() sendMessageToServer(buttonPin) end))
then
ledOn(ledGreen)
print("Message sent.")
else
ledOn(ledRed)
print("Error: Message could not be sent.")
end
But it should run... if I simply remove the word pcall
, making the function run regularly, the crash occurs as expected.
Best regards, Jens
UPDATE: Complete code and intentionally caused error
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()
Error when not using 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
Display with pcall used:
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...
So I'm not manually signalling the error.