Funkcja error()
Proszę zgłaszać błędy za pomocą error() oraz poznać poziomy błędów i komunikaty.
Funkcja error() to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 1 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.
Zgłaszanie błędów
error(message, level) zgłasza błąd Lua. Wykonywanie zostaje zatrzymane, a błąd propaguje się w górę stosu wywołań, dopóki nie zostanie przechwycony przez pcall lub xpcall, albo dopóki nie zakończy działania programu. Komunikatem może być dowolna wartość — łańcuch znaków, tabela lub liczba.
local function divide(a, b)
if b == 0 then
error("division by zero")
end
return a / b
end
print(divide(10, 2)) -- 5.0
-- divide(10, 0) -- ERROR: division by zeroPoziomy błędów
Drugi argument funkcji error() określa miejsce zgłoszenia błędu. Poziom 1 (domyślny) wskazuje samo wywołanie error(). Poziom 2 wskazuje kod wywołujący. Poziom 0 nie dodaje informacji o pozycji. W funkcjach bibliotecznych należy używać poziomu 2, aby wskazać kod użytkownika jako źródło problemu.
local function assertPositive(n, name)
if n <= 0 then
error((name or "value") .. " must be positive, got " .. n, 2)
-- level 2: blame the caller, not this function
end
return n
end
local function compute(x)
assertPositive(x, "x") -- error points here if x <= 0
return math.sqrt(x)
end
compute(-5) -- error: "x must be positive, got -5" at compute() callBłąd z obiektami typu table
Przekazanie tabeli jako wartości błędu umożliwia kodowi wywołującemu odczytanie ustrukturyzowanych informacji o błędzie: kodu błędu, komunikatu i kontekstu. Jest to bardziej informacyjne niż zwykły łańcuch znaków i umożliwia programową obsługę błędów.
local function openDB(host, port)
if port < 1 or port > 65535 then
error({code="INVALID_PORT", port=port,
msg="port out of range: " .. port})
end
-- ... connect
return {host=host, port=port}
end
local ok, err = pcall(openDB, "localhost", -1)
if not ok and type(err) == "table" then
print("Code:", err.code) -- INVALID_PORT
print("Port:", err.port) -- -1
print("Msg:", err.msg)
endassert() jako skrót składniowy
assert(v, msg) jest równoważne if not v then error(msg, 2) end; return v, .... Jest to idiomatyczny sposób sprawdzania warunków wstępnych. Jeśli v ma wartość prawdziwą, assert zwraca wszystkie swoje argumenty (co jest przydatne przy łączeniu wywołań).
local function sqrt(n)
assert(type(n) == "number", "expected number, got " .. type(n))
assert(n >= 0, "sqrt of negative: " .. n)
return math.sqrt(n)
end
print(sqrt(16)) -- 4.0
print(sqrt(2)) -- 1.4142...
-- sqrt("hi") -- ERROR: expected number, got stringerror() a return nil,err
Istnieją dwie konwencje sygnalizowania niepowodzenia: error() (styl wyjątków) albo return nil, msg (styl funkcyjny). Używaj error() w przypadku rzeczywiście nieoczekiwanych sytuacji (błędów programistycznych, naruszenia kontraktu). Używaj nil, msg w przypadku oczekiwanych niepowodzeń (brak pliku, przekroczenie limitu czasu sieci).
-- Exception style (programming error)
local function mustExist(t, key)
local v = t[key]
if v == nil then error("required key missing: " .. key, 2) end
return v
end
-- Functional style (expected failure)
local function findUser(id)
-- ... database query
return nil, "user not found" -- expected: user may not exist
endBłędy w metametodach
Błędy mogą być zgłaszane wewnątrz metametod. Jeśli metametoda zgłosi błąd, propaguje się on do kodu, który wywołał daną operację (na przykład wyrażenie arytmetyczne). W metametodach należy zawsze zabezpieczać się przed nieprawidłowymi danymi wejściowymi.
local SafeDiv = {}
SafeDiv.__index = SafeDiv
SafeDiv.__div = function(a, b)
if b.value == 0 then
error("SafeDiv: division by zero", 2)
end
return SafeDiv.new(a.value / b.value)
end
function SafeDiv.new(v)
return setmetatable({value=v}, SafeDiv)
end
local a = SafeDiv.new(10)
local b = SafeDiv.new(0)
local ok, err = pcall(function() return a / b end)
print(ok, err)Własne typy błędów
Proszę utworzyć funkcję pomocniczą do budowania obiektów błędów z typem. Należy dołączyć znacznik typu, aby kod wywołujący mógł rozróżniać różne rodzaje błędów i odpowiednio je obsługiwać.
local function newError(kind, msg, extra)
return setmetatable(
{kind=kind, message=msg, extra=extra},
{__tostring = function(e)
return "[" .. e.kind .. "] " .. e.message
end}
)
end
local E = {
notFound = function(name) return newError("NOT_FOUND","not found: "..name) end,
badInput = function(msg) return newError("BAD_INPUT", msg) end,
}
local ok, err = pcall(error, E.notFound("config.json"))
if not ok then print(err.kind, err.message) endPropagacja błędów
Gdy funkcja wywołuje inną funkcję, która zgłasza błąd, błąd automatycznie propaguje się w górę stosu. Nie trzeba zgłaszać go ponownie — wystarczy go nie przechwytywać. Błędy należy przechwytywać dopiero na poziomie, na którym można je sensownie obsłużyć lub zgłosić.
local function step3() error("step3 failed") end
local function step2() step3() end
local function step1() step2() end
local ok, err = pcall(step1)
if not ok then
-- err includes the source location
print("Caught at top level:", err)
end
-- Error: input:1: step3 failedŚlad stosu za pomocą debug.traceback
Zwykłe error() dostarcza jedną linię informacji kontekstowych. Aby uzyskać pełny ślad stosu, należy użyć debug.traceback(msg) jako wartości błędu. Zwykle robi się to w module obsługi xpcall.
local function buggy()
local t = nil
return t.field -- nil indexing: error
end
local ok, err = xpcall(buggy, function(e)
return debug.traceback(e, 2) -- full stack trace
end)
if not ok then
print(err) -- full traceback
endPonowne zgłaszanie błędów
Czasami przechwytuje się błąd, aby dodać kontekst, a następnie zgłasza ponownie. Podczas ponownego zgłaszania błędu tekstowego należy użyć error(err, 0) (poziom 0), aby uniknąć dodania kolejnego prefiksu lokalizacji do już sformatowanego komunikatu.
local function loadAndParse(path)
local ok, err = pcall(function()
local f = io.open(path, "r")
if not f then error("cannot open: " .. path) end
local content = f:read("a")
f:close()
return content
end)
if not ok then
error("loadAndParse failed: " .. err, 0) -- re-raise with context
end
end
local ok2, msg = pcall(loadAndParse, "missing.txt")
print(ok2, msg)Szybkie sprawdzenie
Co oznacza poziom 2 w wywołaniu error("msg", 2)?
Podsumowanie: error()
Podsumowanie:
error(msg, level)— zgłasza błąd; poziom 2 wskazuje jako winowajcę kod wywołujący- Tabele służą do przechowywania ustrukturyzowanych błędów z typem i kontekstem
assert(v, msg)— idiomatyczne sprawdzanie warunku wstępnegoerror()służy do błędów w kodzie; w przypadku oczekiwanych niepowodzeń należy zwracać nil+err- Błąd należy ponownie zgłaszać za pomocą
error(err, 0), aby zachować format komunikatu
Często zadawane pytania
Czy lekcja „Funkcja error()” jest bezpłatna?
Tak — pełny tekst „Funkcja error()” 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 „Funkcja error()”?
Proszę zgłaszać błędy za pomocą error() oraz poznać poziomy błędów i komunikaty. Ć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 1 z 4.
Ile czasu zajmuje lekcja „Funkcja error()”?
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