English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Lua エラーハンドリング

プログラムの実行中にエラーハンドリングは必要です。ファイル操作、データ転送、web service呼び出しの過程で予期せぬエラーが発生します。エラーメッセージの処理に注意を払わないと、情報漏洩やプログラムの動作不良が発生する可能性があります。

どのプログラミング言語でも、エラーハンドリングが必要です。エラータイプには:

  • 構文エラー

  • 実行エラー

構文エラー

構文エラーは、プログラムのコンポーネント(演算子、式など)の使用が不適切であるため発生します。以下に簡単な例を示します:

-- test.lua ファイル
a == 2

上記のコードの実行結果は以下の通りです:

lua: test.lua:2: syntax error near '=='

あなたが見たように、上記に構文エラーが発生しました。一つの"="と二つの"="は異なります。一つの"="は代入演算子であり、二つの"="は比較演算子です。

別の例:

for a= 1,10
   print(a)
end

上記のプログラムを実行すると、以下のようなエラーが発生します:

lua: test2.lua:2: 'do' expected near 'print'

構文エラーは、実行エラーよりもシンプルです。実行エラーは具体的なエラーの場所を特定することができませんが、構文エラーはすぐに解決できます。以下の例では、for文の下にdoを追加するだけで解決できます:

for a= 1,10
do
   print(a)
end

実行エラー

実行エラーは、プログラムが正常に実行されるが、エラーメッセージを出力する場合です。以下の例では、引数の入力が間違っているため、プログラムの実行中にエラーが発生します:

function add(a,b)
   return a+b
end
add(10)

以下のコードをコンパイルして実行すると、コンパイルは成功しますが、実行中に以下のようなエラーが発生します:

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
    test2.lua:2: in function 'add'
    test2.lua:5: メインブロックで
    [C]: ?

luaでは、関数を呼び出す際に、実引数リストと引数リストが一致しなくても成功して呼び出すことができます。余分な引数は捨てられ、欠けている引数はnilに補完されます。

上記のエラーメッセージは、引数bがnilに補完された後、nilが計算に参加したためです。 + 計算。

仮に add 関数内では "return a+b" そして "print(a,b)" それでは、結果は以下のようになります: "10 nil" エラーは発生しません。

エラーハンドリング

私たちには、エラーハンドリングを行うための「assert」と「error」の二つの関数を使用できます。以下に例を示します:

local function add(a,b)
   assert(type(a) == "number", "a 不是一个数字")
   assert(type(b) == "number", "b 不是一个数字")
   return a+b
end
add(10)

上記のプログラムを実行すると、以下のようなエラーが発生します:

lua: test.lua:3: b は数値ではありません
stack traceback:
    [C]: in function 'assert'
    test.lua:3: in local 'add'
    test.lua:6: メインブロックで
    [C]: で

例では、assertは最初の引数をチェックし、問題がなければ何もしない;問題があれば、assertは第2引数をエラーメッセージとして投げ出します。

error関数

文法形式:

error(message[, level])

機能:実行中の関数を終了し、メッセージの内容をエラーメッセージとして返します(error関数は決して返り値を返しません)

通常、errorはエラーメッセージのヘッダーにエラーポイント情報を付加します。

Levelパラメータはエラー位置を取得する指示です

  • Level=1[デフォルト]:エラー位置(ファイル)+行号)

  • Level=2:errorを呼び出す関数の関数を指します

  • Level=0: エラーポイント情報を追加しません

pcall、xpcall、debug

Luaでエラーを処理するには、pcall(protected call)関数を使用して実行するコードを包装することができます。

pcallは関数とその後者に渡す引数を受け取り、実行し、実行結果:エラーあり、エラーなし;trueまたはfalse、errorinfoが返されます。

文法形式は以下の通りです

if pcall(function_name, ….) then
-- エラーなし
else
-- いくつかのエラー
end

簡単な例:

> =pcall(function(i) print(i) end, 33)
33
true
   
> =pcall(function(i) print(i) error('error..') end, 33)
33
false stdin:1: error..

ここに注意してください:返り値の論理的な判定:

> function f() return false,2 end
> if f() then print '1else print '0' end
0

pcallは「保護モード」で第1引数を呼び出すため、pcallは関数実行中のどんなエラーもキャッチできます。

通常、エラーが発生した場合、エラーポイントよりも多くのデバッグ情報を得たいですが、pcallが返るときには、コールスタックの一部が破壊されます。

Luaはxpcall関数を提供しており、xpcallは第2引数としてエラーハンドリング関数を受け取り、エラーが発生した場合、Luaはエラーハンドリング関数を呼び出し、コールスタックの展開(unwind)前に呼び出されるため、この関数内でdebugライブラリを使用してエラーに関する追加情報を取得することができます。

debugライブラリは一般的なエラーハンドリング関数を提供しています:

  • debug.debug:ユーザーがエラーカauseを確認できるLuaプロンプトを提供

  • debug.traceback:呼び出し桟に基づいて拡張されたエラーメッセージを構築

>=xpcall(function(i) print(i) error('error..') end, function() print(debug.traceback()) end, 33)
33
stack traceback:
stdin:1: function <stdin:>1>
[C]: function 'error'で
stdin:1: function <stdin:>1>
[C]: function 'xpcall'で
stdin:1: メインブロックで
[C]: で
false        nil

xpcall 使用例 2:

function myfunction ()
   n = n/nil
end
function myerrorhandler( err )
   print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status )

上記のプログラムを実行すると、以下のようなエラーが発生します:

ERROR:2.lua:2: 統合試行における算術演算の試み - グローバルの 'n' (nil 値)
false