error()関数
error()でエラーを発生させ、エラーレベルとメッセージを理解します。
「error()関数」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
エラーを発生させる
error(message, level)はLuaのエラーを発生させます。実行は停止し、pcallまたはxpcallで捕捉されるか、プログラムが終了するまで、エラーは呼び出しスタックを上へ伝播します。メッセージには文字列、テーブル、数値など、任意の値を指定できます。
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エラーレベル
error()の2番目の引数は、エラーをどこで報告するかを制御します。レベル1(デフォルト)はerror()の呼び出し自体を示します。レベル2は呼び出し元を示します。レベル0では位置情報を追加しません。ライブラリ関数では、ユーザーのコードに原因があることを示すためにレベル2を使用します。
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テーブルオブジェクトを使ったエラー
エラー値としてテーブルを渡すと、呼び出し元はエラーコード、メッセージ、コンテキストなどの構造化されたエラー情報を調べられます。単純な文字列よりも情報量が多く、プログラムからエラーを処理できます。
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()
assert(v, msg)はif not v then error(msg, 2) end; return v, ...と同等です。事前条件の確認に使う慣用的な方法です。vがtruthyの場合、assertはすべての引数を返すため、メソッドチェーンにも利用できます。
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()とreturn nil,errの違い
失敗を通知する規約には、error()(例外形式)とreturn nil, msg(関数型形式)の2つがあります。error()は、予期しない状態(プログラミング上のバグや契約違反)に使用します。nil, msgは、想定される失敗(ファイルが見つからない、ネットワークがタイムアウトするなど)に使用します。
-- 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メタメソッド内のエラー
メタメソッド内でエラーを発生させることもできます。メタメソッドでエラーが発生すると、算術式など、その操作を引き起こしたコードへ伝播します。メタメソッドでは、無効な入力に対して必ず対策してください。
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)カスタムエラー型
型付きエラーオブジェクトを作成するヘルパーを用意します。型タグを含めることで、呼び出し側が異なる種類のエラーを区別し、それぞれに適切に対処できるようにします。
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エラーの伝播
ある関数がエラーを返す別の関数を呼び出すと、そのエラーは自動的にスタックを上へ伝播します。再スローする必要はありません。単に捕捉しなければよいのです。エラーを意味のある形で処理または報告できるレベルでのみ、エラーを捕捉してください。
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 faileddebug.traceback によるスタックトレース
通常の error() では、コンテキストが1行だけ示されます。完全なスタックトレースが必要な場合は、エラー値として debug.traceback(msg) を使用します。これは通常、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
endエラーの再スロー
エラーを捕捉してコンテキストを追加した後、再スローすることがあります。文字列エラーを再スローする際は、すでに整形されたメッセージに位置情報のプレフィックスが追加されないよう、error(err, 0)(レベル0)を使用します。
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)理解度チェック
error("msg", 2) のレベル2は何を意味しますか?
まとめ: error()
まとめ:
error(msg, level)— エラーを発生させます。レベル2では呼び出し元が原因として示されます- 型とコンテキストを持つ構造化エラーにはテーブルを使用します
assert(v, msg)— 慣用的な事前条件チェックです- バグには
error()を使用し、予期される失敗には nil+err を返します - メッセージ形式を保持するには
error(err, 0)で再スローします
よくある質問
「error()関数」レッスンは無料ですか?
はい。「error()関数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「error()関数」で何を学びますか?
error()でエラーを発生させ、エラーレベルとメッセージを理解します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「error()関数」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。