Lua
Obsługa błędów
Szukaj…
Korzystanie z pcall
pcall
oznacza „chronione połączenie”. Służy do dodawania obsługi błędów do funkcji. pcall
działa podobnie jak try-catch
w innych językach. Zaletą pcall
jest to, że całe wykonywanie skryptu nie jest przerywane, jeśli wystąpią błędy w funkcjach wywoływanych z pcall
. Jeśli wystąpi błąd w funkcji wywołanej przez pcall
jest błąd, a reszta kodu kontynuuje wykonywanie.
Składnia:
pcall( f , arg1,···)
Zwracane wartości:
Zwraca dwie wartości
- status (boolean)
- Zwraca true, jeśli funkcja została wykonana bez błędów.
- Zwraca false, jeśli wystąpił błąd wewnątrz funkcji.
- zwraca wartość funkcji lub komunikat o błędzie, jeśli błąd wystąpił w bloku funkcji.
pcall może być używany w różnych przypadkach, jednak powszechnym jest wychwytywanie błędów z funkcji, która została nadana twojej funkcji. Załóżmy na przykład, że mamy tę funkcję:
local function executeFunction(funcArg, times) then
for i = 1, times do
local ran, errorMsg = pcall( funcArg )
if not ran then
error("Function errored on run " .. tostring(i) .. "\n" .. errorMsg)
end
end
end
Gdy dana funkcja popełni błąd podczas uruchomienia 3, komunikat o błędzie będzie jasny dla użytkownika, że nie pochodzi on z twojej funkcji, ale z funkcji, która została przekazana naszej funkcji. Mając to na uwadze, można stworzyć fantazyjne BSoD powiadamiające użytkownika. Jednak to zależy od aplikacji, która implementuje tę funkcję, ponieważ interfejs API najprawdopodobniej tego nie zrobi.
Przykład A - Wykonanie bez pcall
function square(a)
return a * "a" --This will stop the execution of the code and throws an error, because of the attempt to perform arithmetic on a string value
end
square(10);
print ("Hello World") -- This is not being executed because the script was interrupted due to the error
Przykład B - Wykonanie z pcall
function square(a)
return a * "a"
end
local status, retval = pcall(square,10);
print ("Status: ", status) -- will print "false" because an error was thrown.
print ("Return Value: ", retval) -- will print "input:2: attempt to perform arithmetic on a string value"
print ("Hello World") -- Prints "Hello World"
Przykład - wykonanie bezbłędnego kodu
function square(a)
return a * a
end
local status, retval = pcall(square,10);
print ("Status: ", status) -- will print "true" because no errors were thrown
print ("Return Value: ", retval) -- will print "100"
print ("Hello World") -- Prints "Hello World"
Obsługa błędów w Lua
Zakładając, że mamy następującą funkcję:
function foo(tab)
return tab.a
end -- Script execution errors out w/ a stacktrace when tab is not a table
Poprawmy to trochę
function foo(tab)
if type(tab) ~= "table" then
error("Argument 1 is not a table!", 2)
end
return tab.a
end -- This gives us more information, but script will still error out
Jeśli nie chcemy, aby funkcja powodowała awarię programu nawet w przypadku wystąpienia błędu, w lua standardowo wykonuje się następujące czynności:
function foo(tab)
if type(tab) ~= "table" then return nil, "Argument 1 is not a table!" end
return tab.a
end -- This never crashes the program, but simply returns nil and an error message
Teraz mamy taką funkcję, możemy robić takie rzeczy:
if foo(20) then print(foo(20)) end -- prints nothing
result, error = foo(20)
if result then print(result) else log(error) end
A jeśli chcemy, aby program się zawiesił, jeśli coś pójdzie nie tak, nadal możemy to zrobić:
result, error = foo(20)
if not result then error(error) end
Na szczęście nie musimy nawet pisać tego wszystkiego za każdym razem; lua ma dokładnie taką funkcję
result = assert(foo(20))