Wywołania chronione za pomocą pcall
Proszę bezpiecznie przechwytywać błędy za pomocą pcall i interpretować zwracane wartości.
Wywołania chronione za pomocą pcall to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.
Podstawy pcall
pcall(f, ...) wywołuje funkcję f z argumentami ... w trybie chronionym. Jeśli f zakończy się pomyślnie, pcall zwraca true, a następnie wszystkie wartości zwrócone przez funkcję. Jeśli f zgłosi błąd, pcall zwraca false, a następnie komunikat błędu. W obu przypadkach program działa dalej.
local function risky(x)
if x < 0 then error("negative input: " .. x) end
return math.sqrt(x)
end
local ok, result = pcall(risky, 9)
print(ok, result) -- true 3.0
ok, result = pcall(risky, -1)
print(ok, result) -- false ...: negative input: -1Przechwytywanie konkretnych błędów
Po użyciu pcall należy sprawdzić typ wartości błędu, aby różne rodzaje błędów obsługiwać w różny sposób. Błędy będące tabelami zawierają dane strukturalne, a błędy tekstowe — komunikat. Należy zawsze obsługiwać oba przypadki.
local function op(errType)
if errType == "table" then
error({code=42, msg="structured error"})
else
error("plain string error")
end
end
local ok, err = pcall(op, "table")
if not ok then
if type(err) == "table" then
print("Code:", err.code, "Msg:", err.msg)
else
print("String error:", err)
end
endWiele wartości zwracanych po sukcesie
Po pomyślnym wykonaniu pcall zwraca wszystkie wartości zwrócone przez chronioną funkcję, poprzedzone początkową wartością true. Należy przypisać je do wielu zmiennych.
local function compute(a, b)
return a + b, a * b, a - b
end
local ok, sum, product, diff = pcall(compute, 6, 4)
if ok then
print("sum:", sum, "product:", product, "diff:", diff)
-- sum: 10 product: 24 diff: 2
endZagnieżdżanie pcall
Wywołania pcall można zagnieżdżać. Każde pcall tworzy niezależny chroniony zakres. Błąd w wewnętrznym pcall zostanie przechwycony przez wewnętrzne pcall, a nie przez zewnętrzne. Umożliwia to implementowanie strategii awaryjnych.
local function tryPrimary()
error("primary failed")
end
local function tryFallback()
return "fallback result"
end
local ok, result = pcall(tryPrimary)
if not ok then
print("Primary failed:", result)
ok, result = pcall(tryFallback)
end
if ok then print("Got:", result) end -- fallback resultpcall z metodami
Aby wywołać metodę (składnia z dwukropkiem) za pomocą pcall, należy przekazać funkcję i obiekt jako pierwszy argument. Można użyć pcall(obj.method, obj, args...) albo opakować wywołanie w domknięcie.
local obj = {
x = 10,
compute = function(self, n)
if n == 0 then error("zero divisor") end
return self.x / n
end
}
-- Pass method + self explicitly
local ok, v = pcall(obj.compute, obj, 2)
print(ok, v) -- true 5.0
-- Or use a closure
ok, v = pcall(function() return obj:compute(0) end)
print(ok, v) -- false ...zero divisorpcall dla bezpieczeństwa operacji wejścia-wyjścia
Operacje wejścia-wyjścia należy opakować w pcall, aby przechwytywać nieoczekiwane błędy systemu operacyjnego. Należy zwracać spójną parę wynik/błąd, aby kod wywołujący mógł poprawnie obsługiwać niepowodzenia.
local function safeRead(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local content = f:read("a")
f:close()
return content
end)
if ok then return result
else return nil, result
end
end
local data, err = safeRead("config.txt")
if data then print("Read", #data, "bytes")
else print("Error:", err)
endWzorzec ponawiania z pcall
Należy ponawiać zawodne operacje (żądanie sieciowe, zapis pliku) maksymalnie N razy, używając pcall do przechwytywania błędów. W rzeczywistym kodzie między próbami należy wstrzymać wykonanie (lub użyć coroutine).
local function retry(fn, maxAttempts)
local attempts = 0
while attempts < maxAttempts do
attempts = attempts + 1
local ok, result = pcall(fn)
if ok then
print("Succeeded on attempt", attempts)
return result
end
print("Attempt", attempts, "failed:", result)
end
error("all " .. maxAttempts .. " attempts failed")
end
local n = 0
retry(function()
n = n + 1
if n < 3 then error("not ready") end
return "done"
end, 5)Zapisywanie wyników pcall w tabeli
Gdy pcall jest używane w pętli, wyniki należy przechowywać w tabeli do późniejszej analizy. Jest to przydatne podczas operacji wsadowych, gdy chcą Państwo przetworzyć wszystkie elementy i zebrać błędy zamiast zatrzymywać się przy pierwszym niepowodzeniu.
local jobs = {10, -5, 25, 0, 16}
local results = {}
for _, n in ipairs(jobs) do
local ok, v = pcall(function()
if n < 0 then error("negative") end
return math.sqrt(n)
end)
results[#results+1] = {input=n, ok=ok, value=v}
end
for _, r in ipairs(results) do
if r.ok then
print(r.input, "->", string.format("%.3f", r.value))
else
print(r.input, "-> ERROR:", r.value)
end
endpcall a xpcall
pcall przechwytuje błąd, ale udostępnia tylko jego wartość. xpcall pozwala przekazać funkcję obsługi komunikatu, która działa, gdy stos jest jeszcze nienaruszony, dzięki czemu można uzyskać ślady stosu. Należy wybrać xpcall, gdy potrzebne są ślady stosu.
-- pcall: simple, no traceback
local ok1, err1 = pcall(function()
error("simple error")
end)
print(err1) -- only the error message
-- xpcall: with traceback handler
local ok2, err2 = xpcall(
function() error("traced error") end,
function(e) return debug.traceback(e, 2) end
)
print(err2) -- full stack traceKonwencja wartości zwracanych przez pcall
pcall należy stosować jako podstawę spójnego API: po pomyślnym wykonaniu zawsze zwracać value, a po niepowodzeniu nil, errorMessage. Funkcje należy budować w ten sposób, aby kod wywołujący zawsze wiedział, czego się spodziewać.
local function loadJSON(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local text = f:read("a")
f:close()
-- Fake JSON parse for demo
return {data = text, path = path}
end)
if ok then return result
else return nil, result
end
end
local data, err = loadJSON("data.json")
if data then print("Loaded:", data.path)
else print("Failed:", err)
endSzybkie sprawdzenie
Co zwraca pcall, gdy chroniona funkcja zakończy się pomyślnie?
Podsumowanie: pcall
Podsumowanie:
pcall(f, ...)→true, results...albofalse, err- Należy sprawdzić pierwszą wartość zwracaną, aby określić powodzenie lub niepowodzenie
- Po wartości true w przypadku sukcesu występuje wiele wartości zwracanych
- Zagnieżdżone pcall: każde niezależnie przechwytuje własne błędy
- Wzorzec ponawiania: pętla z pcall dla zawodnych operacji
- Należy użyć xpcall, gdy potrzebne są ślady stosu
Często zadawane pytania
Czy lekcja „Wywołania chronione za pomocą pcall” jest bezpłatna?
Tak — pełny tekst „Wywołania chronione za pomocą pcall” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wywołania chronione za pomocą pcall”?
Proszę bezpiecznie przechwytywać błędy za pomocą pcall i interpretować zwracane wartości. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Lua Academy?
Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Wywołania chronione za pomocą pcall”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?
Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Funkcja error()
- Wywołania chronione za pomocą pcall
- xpcall i programy obsługi komunikatów
- Strukturalne obiekty błędów