Luaには他の言語でよくあるtry~の例外処理が存在しない代わりに、pcall/xpcallというエラー処理用の関数が標準で用意されています。
この記事では、pcall/xpcallの使い方とサンプルコード、それと、おまけで自作エラーの作り方とサンプルコードをまとめています。
Luaでのエラー処理の書き方
Luaでエラー処理を行う場合は、pcall()またはxpcall()を使用します。
※pcall/xpcall内では、Luaがprotected modeで実行される仕組みのため、エラーが発生してもpcall/xpcall内でキャッチされます
pcall()とxpcall()の違いは、メッセージハンドラを使用するかどうかの違いです。
メッセージハンドラにはトレース情報等を使用できるため、トレース情報等を使う場合はxpcall()を使います。
通常のエラーメッセージのみの場合はpcall()で十分です。
pcallの場合
pcall()は以下の形式で呼び出します。pcall(<エラーが起きる可能性のある関数>, [関数の引数1], [関数の引数2], ...)
エラーの発生有無はpcallの返り値で判断できます。
エラー発生有 | エラー発生無 | |
---|---|---|
1つ目の返り値 | false | true |
2つ目の返り値 | エラーメッセージ | 関数の実際の返り値 (複数の返り値がある場合は3つ目、4つ目…に設定される) |
エラー発生有/無それぞれのサンプルコードは以下です。
-- エラーが発生する関数の例 (引数が'abc'以外の場合にエラー)
function hogeFunction(str)
if str ~= 'abc' then
error('DUMMY ERROR')
end
return 'ABC'
end
-- エラーが発生しない呼び出しの場合
pcallResult, functionReturn = pcall(hogeFunction, 'abc')
-- 1つ目の返り値にtrue、2つ目以降の返り値に指定した関数の実際の返り値が設定される
print(pcallResult .. ', ' .. functionReturn)
-- > true, ABC
-- エラーが発生する呼び出しの場合
pcallResult, functionReturn = pcall(hogeFunction, '123')
-- 1つ目の返り値にfalse、2つ目の返り値にエラーメッセージが設定される
print(pcallResult .. ', ' .. functionReturn)
-- > false, [string "GEConsole"]1:1 DUMMY ERROR
xpcallの場合
xpcall()は以下の形式で呼び出します。xpcall(<エラーが起きる可能性のある関数>, <メッセージハンドラ>, [関数の引数1], [関数の引数2], ...)
メッセージハンドラを指定する以外はpcall()と同じであるため、返り値等の説明は省略します。
Lua標準のdebug.tracebackをメッセージハンドラに指定する場合のサンプルコードを以下に示します。
-- エラーが発生する関数の例 (引数が'abc'以外の場合にエラー)
function hogeFunction(str)
if str ~= 'abc' then
error('DUMMY ERROR')
end
return 'ABC'
end
-- エラーが発生しない呼び出しの場合
xpcallResult, functionReturn = xpcall(hogeFunction, debug.traceback, 'abc')
-- 1つ目の返り値にtrue、2つ目以降の返り値に指定した関数の実際の返り値が設定される
print(xpcallResult .. ', ' .. functionReturn)
-- > true, ABC
-- エラーが発生する呼び出しの場合
xpcallResult, functionReturn = xpcall(hogeFunction, debug.traceback, '123')
-- 1つ目の返り値にfalse、2つ目の返り値にエラーメッセージが設定される
print(pcallResult .. ', ' .. functionReturn)
-- > false, debug.tracebackの中身(↓参照)
自作のエラーを発生させる方法
上のサンプルコードでしれっと書いていましたが、LuaでもPythonのraiseのように自分でエラーを発生させることが可能です。
自分でエラーを発生させる場合はerror()を使用します。
error()を呼び出すとその時点でエラーが発生し(前述のpcall/xpcallでキャッチしない場合)、プログラムが終了します。
error()は以下の形式で呼び出します。error(<エラーメッセージ>, [エラー情報の階層])
なお、エラーメッセージには自動的に行数等の情報が付与されます。
例えばerror('DUMMY ERROR')
という呼び出しを行った場合、エラーメッセージは'[string "GEConsole"]1:1 DUMMY ERROR'
となります。
※付与される情報は環境によって異なります。
付与される情報はerror()の第二引数で変更可能です。
デフォルトは1となっており、1の場合はerror()を呼び出した行数等がエラーメッセージに付与されます。
2を指定した場合は、error()を呼び出した関数を呼び出した箇所がエラーメッセージに付与されます。
後はご想像の通り、3, 4…と指定する数が大きいほど呼び出しが上の階層の情報が付与されます。
なお、0を指定した場合は情報の付与が行われません。
上の章で登場済みですが、一応ここにもサンプルコードを置いておきます。
-- エラーが発生する関数の例 (引数が'abc'以外の場合にエラー)
function hogeFunction(str)
if str ~= 'abc' then
error('DUMMY ERROR')
-- エラーメッセージは、"↑の行数等の情報 + DUMMY ERROR"
end
return 'ABC'
end
-- エラーメッセージに行数等の情報を付与したくない場合
function hogeFunction2(str)
if str ~= 'abc' then
error('DUMMY ERROR', 0)
-- エラーメッセージは、"DUMMY ERROR"のみ
end
return 'ABC'
end
参考
https://www.lua.org/manual/5.4/manual.html#2.3
https://www.lua.org/manual/5.4/manual.html#pdf-pcall
https://www.lua.org/manual/5.4/manual.html#pdf-xpcall
https://www.lua.org/manual/5.4/manual.html#pdf-error
https://www.lua.org/manual/5.4/manual.html#pdf-debug.traceback
コメント