Lua - Obsługa błędów
Potrzeba obsługi błędów
Obsługa błędów jest dość krytyczna, ponieważ operacje w świecie rzeczywistym często wymagają użycia złożonych operacji, które obejmują operacje na plikach, transakcje w bazie danych i wywołania usług internetowych.
W każdym programowaniu zawsze wymagana jest obsługa błędów. Błędy mogą być dwojakiego rodzaju, w tym:
- Błędy składniowe
- Błędy czasu wykonywania
Błędy składniowe
Błędy składniowe występują z powodu niewłaściwego użycia różnych składników programu, takich jak operatory i wyrażenia. Poniżej przedstawiono prosty przykład błędu składniowego.
a == 2
Jak wiesz, istnieje różnica między używaniem pojedynczego „równego” i podwójnego „równego”. Używanie jednego zamiast drugiego może prowadzić do błędu. Jedno „równe” odnosi się do przypisania, a podwójne „równe” odnosi się do porównania. Podobnie mamy wyrażenia i funkcje, które mają predefiniowane sposoby implementacji.
Kolejny przykład błędu składniowego pokazano poniżej -
for a= 1,10
print(a)
end
Po uruchomieniu powyższego programu otrzymamy następujące dane wyjściowe -
lua: test2.lua:2: 'do' expected near 'print'
Błędy składniowe są znacznie łatwiejsze w obsłudze niż błędy czasu wykonania, ponieważ interpreter Lua lokalizuje błąd wyraźniej niż w przypadku błędu wykonania. Z powyższego błędu, możemy łatwo wiedzieć, że dodanie zrób oświadczenia przed instrukcja print jest wymagane zgodnie strukturze Lua.
Błędy czasu wykonywania
W przypadku błędów w czasie wykonywania program wykonuje się pomyślnie, ale może to skutkować błędami w czasie wykonywania z powodu błędów w danych wejściowych lub nieprawidłowej obsługi funkcji. Poniżej przedstawiono prosty przykład pokazujący błąd czasu wykonywania.
function add(a,b)
return a+b
end
add(10)
Kiedy budujemy program, będzie się on budował i działał. Po uruchomieniu wyświetla błąd czasu wykonywania.
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
test2.lua:2: in function 'add'
test2.lua:5: in main chunk
[C]: ?
Jest to błąd w czasie wykonywania, który wystąpił z powodu nieprzekazywania dwóch zmiennych. Plikb jest oczekiwany i tutaj jest zerowy i powoduje błąd.
Funkcje asertu i błędu
Aby poradzić sobie z błędami, często używamy dwóch funkcji - assert i error. Poniżej przedstawiono prosty przykład.
local function add(a,b)
assert(type(a) == "number", "a is not a number")
assert(type(b) == "number", "b is not a number")
return a+b
end
add(10)
Kiedy uruchomimy powyższy program, otrzymamy następujące wyjście błędu.
lua: test2.lua:3: b is not a number
stack traceback:
[C]: in function 'assert'
test2.lua:3: in function 'add'
test2.lua:6: in main chunk
[C]: ?
Plik error (message [, level])kończy ostatnią wywołaną funkcję chronioną i zwraca komunikat jako komunikat o błędzie. Ten błąd funkcji nigdy nie powraca. Zwykle komunikat o błędzie dodaje pewne informacje o pozycji błędu na początku wiadomości. Argument poziomu określa, w jaki sposób uzyskać pozycję błędu. Przy poziomie 1 (domyślnym) pozycja błędu jest miejscem wywołania funkcji błędu. Poziom 2 wskazuje błąd w miejscu wywołania funkcji, która wywołała błąd; i tak dalej. Przekazanie poziomu 0 pozwala uniknąć dodawania informacji o pozycji błędu do komunikatu.
pcall i xpcall
W programowaniu Lua, aby uniknąć wyrzucania tych błędów i obsługi błędów, musimy użyć funkcji pcall lub xpcall.
Plik pcall (f, arg1, ...)function wywołuje żądaną funkcję w trybie chronionym. Jeśli jakiś błąd wystąpi w funkcji f, nie zgłasza błędu. Po prostu zwraca stan błędu. Poniżej przedstawiono prosty przykład użycia pcall.
function myfunction ()
n = n/nil
end
if pcall(myfunction) then
print("Success")
else
print("Failure")
end
Kiedy uruchomimy powyższy program, otrzymamy następujące dane wyjściowe.
Failure
Plik xpcall (f, err)funkcja wywołuje żądaną funkcję, a także ustawia procedurę obsługi błędów. Żaden błąd wewnątrz f nie jest propagowany; zamiast tego xpcall wychwytuje błąd, wywołuje funkcję err z oryginalnym obiektem błędu i zwraca kod stanu.
Poniżej przedstawiono prosty przykład dla xpcall.
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
Kiedy uruchomimy powyższy program, otrzymamy następujące dane wyjściowe.
ERROR: test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false
Jako programista najważniejsze jest zadbanie o właściwą obsługę błędów w programach, które piszesz. Korzystanie z obsługi błędów może zapewnić obsługę nieoczekiwanych warunków wykraczających poza warunki brzegowe bez przeszkadzania użytkownikowi programu.