例外処理文
例外ハンドラの記述 への移動
例外処理ブロックは、except キーワードで始まり、end キーワードで終わります。 これら 2 つのキーワードは、実際には try ブロックと同じ文の一部です。 つまり、try ブロックと例外処理ブロックはどちらも単一の try...except 文の一部と見なされます。
例外処理ブロック内には、例外ハンドラを 1 つ以上記述します。 例外ハンドラは以下の形式の文です。
on <type of exception> do <statement>;
たとえば、以下の例外処理ブロックには、算術計算で発生するおそれのあるさまざまな例外に対応して複数の例外ハンドラが含まれています。
try
{ calculation statements }
except
on EZeroDivide do Value := MAXINT;
on EIntOverflow do Value := 0;
on EIntUnderflow do Value := 0;
end;
通常は、上記の例で示したように、例外ハンドラには例外の型以外に例外に関する情報は不要なので、on..do の後の文は例外の型にのみ固有のものとなります。 しかし、場合によっては、例外インスタンスに含まれている情報の一部が必要になる可能性もあります。
例外ハンドラで例外インスタンスに関する特定の情報を読み取るには、例外インスタンスにアクセスできるようにする特別な形式の on..do を使用します。 この特別な形式では、例外インスタンスを格納する一時変数を使用する必要があります。 例:
on E: EIntegerRange do
ShowMessage(Format('Expected value between %d and %d', E.Min, E.Max));
一時変数(この例では E)は、コロンの後に指定された型(この例では EIntegerRange)を持ちます。 必要であれば、as 演算子を使用して、例外をより具体的な型に型キャストすることができます。
警告: 一時的な例外オブジェクトを絶対に破棄しないでください。 例外オブジェクトは例外処理で自動的に破棄されます。 オブジェクトを手動で破棄した場合、アプリケーションはオブジェクトを再び破棄しようとするため、アクセス違反が発生します。
単一のデフォルト例外ハンドラを用意して、特定のハンドラを指定していないあらゆる例外を処理することができます。 それには、以下のように、例外処理ブロックに else 部を追加します。
try
{ statements }
except
on ESomething do
{ specific exception-handling code };
else
{ default exception-handling code };
end;
デフォルトの例外処理をブロックに追加すると、あらゆる例外が必ずそのブロックで何らかの方法で処理されることになります。その結果、外側のブロックで指定されるすべての例外処理より優先されます。
警告: すべての例外に対応してしまうこのようなデフォルト例外ハンドラは使用しないことをお勧めします。 else 節では、実体のわからない例外も含めて、あらゆる例外を処理してしまいます。 一般に、コードでは、処理方法が実際にわかっている例外のみ処理するようにします。 クリーンアップ処理のみ行い、例外処理については、例外とその処理方法に関するより多くの情報を持っているコードに任せる場合は、finally ブロックを使ってそれを実現できます。 finally ブロックの詳細については、「finally ブロックの記述」を参照してください。