2017-01-08 3 views
2

Ich habe ein Stück Lua-Code, der eine UDP-Nachricht sendet, die funktioniert. Allerdings möchte ich es mehr fehlerfrei machen. Also habe ich einen falschen DNS-Namen eingegeben, um einen Fehler bei der Auflösung zu provozieren. Es ist mir egal, was in diesem Block scheitert, ich möchte nur in der Lage sein, den Fehler elegant zu behandeln. In anderen Sprachen würde ich Try-Catch verwenden. Hier verstehe ich pcall soll diese Lücke füllen. Also versuche ich pcall zu benutzen und versuche buttonPin an die sendMessageToServer() Funktion zu übergeben.Lua: Verwendung von pcall

Dieser Ansatz nicht funktioniert, nichts gefangen wird, die ganzen Knoten abstürzt:

if(pcall(sendMessageToServer, buttonPin)) 
then 
    ledOn(ledGreen) 
    print("Message sent.") 
else 
    ledOn(ledRed) 
    print("Error: Message could not be sent.") 
end 

Dieser Ansatz macht das Gegenteil: Es stürzt nicht und sieht aus, als ob alles in Ordnung ist, so pcall true zurück:

if(pcall(function() sendMessageToServer(buttonPin) end)) 
then 
    ledOn(ledGreen) 
    print("Message sent.") 
else 
    ledOn(ledRed) 
    print("Error: Message could not be sent.") 
end 

Aber es sollte laufen ... wenn ich das Wort pcall einfach entfernen, regelmäßig die Funktion Durchlauf zu machen, der Absturz wie erwartet auftritt.

Mit freundlichen Grüßen, Jens

UPDATE: Vollständige Code und absichtlich verursachte Fehler

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() 

Fehler, wenn sie nicht mit 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 mit pcall verwendet:

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... 

Also ich signalisiere nicht manuell den Fehler.

+0

Sie würden mehr Antworten erhalten, wenn Sie genug Respekt gezeigt hätten, um zumindest den Namen der Sprache korrekt einzugeben. Lua ist kein Akronym, kapitalisiert das L, das ist alles. Lua. Bitte beheben Sie die Frage. – warspyking

+0

Können Sie zeigen, wie der Stacktrace für den absichtlich ausgelösten Fehler aussieht? Wie wird der Fehler gemeldet? Verwenden Sie 'error' /' lua_error' oder verwendet Ihr Code eine "Out-of-Band" -Methode, um diesen Fehler zu signalisieren, den lua nicht versteht? – greatwolf

+0

Ich habe meine ursprüngliche Frage aktualisiert, um mehr Code und die Fehlermeldungen zu enthalten. – Jens

Antwort

0

Sie verwenden LuaSockets richtig? Sie sollten wissen, dass die Funktionen in LuaSockets keine Fehler auslösen. Die meisten Funktionen, wie udp send, geben 1 zurück, wenn sie erfolgreich waren, und nil + msg, wenn etwas schief gelaufen ist. Wenn Sie einen Fehler melden möchten, müssen Sie den Rückgabewert überprüfen und den Fehler selbst auslösen. Eine sehr häufige Art und Weise, es zu tun ist, um die Anruf in einer Assertion zu wickeln, wie folgt aus:

assert(conn:send(msg..';'..hash)) 

Wenn Sie sagen, dass es ohne pcall funktioniert dann bist du eigentlich selbst zum Narren. Es sieht aus, als ob Sie wie folgt vorgehen:

if(sendMessageToServer(buttonPin)) 
then 
    ledOn(ledGreen) 
    print("Message sent.") 
else 
    ledOn(ledRed) 
    print("Error: Message could not be sent.") 
end 

Der obige Code wird immer drucken „Fehler: Nachricht kann nicht gesendet werden“ Da die sendMessageToServer Funktion nie etwas zurückgibt, wird in diesem Fall die if-Bedingung immer als false ausgewertet und Sie landen im Block else, unabhängig davon, ob Sie die Daten gesendet haben oder nicht.