Lua Academy · leksjon

Funksjonen error()

Utløs feil med error(), og forstå feilkoder og meldinger.

Leksjon 1 av 412 trinn

Funksjonen error() er en gratis leksjon i Lua Academy på CoddyKit. Dette er leksjon 1 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lua Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lua Academy inneholder totalt 4 leksjoner.

Kaste feil

error(message, level) utløser en Lua-feil. Kjøringen stopper, og feilen forplanter seg oppover i kallstakken til den fanges opp av pcall eller xpcall, eller til programmet avsluttes. Meldingen kan være hvilken som helst verdi — streng, tabell eller tall.

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 zero

Feilnivåer

Det andre argumentet til error() styrer hvor feilen rapporteres. Nivå 1 (standard) peker på selve kallet til error(). Nivå 2 peker på kalleren. Nivå 0 legger ikke til posisjonsinformasjon. Bruk nivå 2 i biblioteksfunksjoner for å angi at feilen ligger i brukerens kode.

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

Feil med tabellobjekter

Hvis De sender en tabell som feilverdi, kan kallere undersøke strukturert feilinformasjon: feilkode, melding og kontekst. Dette er mer informativt enn en vanlig streng og muliggjør programmatisk feilbehandling.

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

assert() som syntaktisk forenkling

assert(v, msg) tilsvarer if not v then error(msg, 2) end; return v, .... Det er idiomatisk å bruke dette til kontroll av forhåndsbetingelser. Hvis v er sann, returnerer assert alle argumentene sine (nyttig ved lenking).

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 string

error() kontra return nil,err

Det finnes to konvensjoner for å angi feil: error() (unntaksstil) eller return nil, msg (funksjonell stil). Bruk error() for virkelig uventede forhold (programmeringsfeil eller brudd på kontrakter). Bruk nil, msg for forventede feil (fil ikke funnet eller tidsavbrudd for nettverk).

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

Feil i metametoder

Feil kan utløses inne i metametoder. Hvis en metametode gir en feil, forplanter den seg til koden som utløste operasjonen (for eksempel et aritmetisk uttrykk). Beskytt alltid metametoder mot ugyldige inndata.

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)

Egendefinerte feiltyper

Opprett en hjelpefunksjon for å bygge typede feilobjekter. Ta med en typeetikett slik at kallere kan skille mellom ulike typer feil og håndtere hver av dem på riktig måte.

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

Feilpropagering

Når en funksjon kaller en annen funksjon som gir en feil, propageres feilen automatisk oppover i stakken. De trenger ikke kaste feilen på nytt – bare la være å fange den. Fang bare feil på det nivået der de kan håndteres eller rapporteres på en meningsfull måte.

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

Stack trace med debug.traceback

Et vanlig error()-kall gir én linje med kontekst. Bruk debug.traceback(msg) som feilverdien for å få en full stack trace. Dette gjøres vanligvis i en xpcall-behandler.

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
end

Kaste feil på nytt

Noen ganger fanger De en feil for å legge til kontekst, og kaster den deretter på nytt. Bruk error(err, 0) (nivå 0) når De kaster en strengfeil på nytt, slik at De unngår å legge til et nytt steds- eller lokasjonsprefiks i en melding som allerede er formatert.

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)

Hurtigsjekk

Hva betyr nivå 2 i error("msg", 2)?

Oppsummering: error()

Oppsummering:

  • error(msg, level) – utløser en feil; nivå 2 angir at den som kalte funksjonen, har skylden
  • Bruk tabeller for strukturerte feil med type og kontekst
  • assert(v, msg) – idiomatisk sjekk av forhåndsbetingelser
  • Bruk error() for programfeil; returner nil+err for forventede feil
  • Kast på nytt med error(err, 0) for å bevare meldingsformatet
Gratis å komme i gang

Lær deg Lua med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
40
Leksjoner
159

Ofte stilte spørsmål

Er leksjonen «Funksjonen error()» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lua Academy, inkludert «Funksjonen error()», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lua Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Funksjonen error()»?

Utløs feil med error(), og forstå feilkoder og meldinger. Du øver på Lua Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Lua Academy?

Ingen tidligere erfaring er nødvendig. Lua Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.

Hvor lang tid tar leksjonen «Funksjonen error()»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Lua Academy-leksjonen?

Ja. Alle Lua Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Funksjonen error()
  2. Beskyttede kall med pcall
  3. xpcall og meldingsbehandlere
  4. Strukturerte feilobjekter
← Tilbake til Lua Academy