$ETRAP (ObjectScript)
構文
$ETRAP
$ET
SET $ETRAP="cmdline"
SET $ET="cmdline"
概要
$ETRAP には、エラーの発生時に実行される 1 つ以上の ObjectScript コマンドを指定する文字列が含まれます。
新しいアプリケーション・コードでのエラー処理では、TRY および CATCH コマンドを使用することを強くお勧めします。ここでは、既存のコードのメンテナンスおよび移行をサポートする $ETRAP について記載します。詳細は、"TRY-CATCH の使用法" を参照してください。
SET コマンドを使用して、$ETRAP に、1 つ以上の ObjectScript コマンドを含む cmdline 文字列の値を指定します。エラーが発生すると、InterSystems IRIS はユーザが $ETRAP に入力したコマンドを実行します。例えば、$ETRAP を、エラー処理ルーチンに制御を移す GOTO コマンドを含む文字列に設定するとします。
SET $ETRAP="GOTO LOGERR^ERRROU"
InterSystems IRIS は、エラー状態を生成する任意の ObjectScript コマンドの直後に、$ETRAP のこのコマンドを実行します。InterSystems IRIS は、エラー状態が発生するコンテキスト・レベルで $ETRAP コマンドを実行します。InterSystems IRIS は、$ETRAP が設定されている場合、有効な $ROLES 値を保存します。$ETRAP コードが実行されると、InterSystems IRIS は $ROLES を保存されたその値に設定します。これにより、$ETRAP エラー・ハンドラは、エラー・ハンドラの設定後にルーチンに付与された上位特権を使用しないようにします。
エラー・ハンドラを実行するように $ETRAP を設定する場合 (GOTO コマンドを使用するなど)、このエラー・ハンドラは、label (現在のルーチンのラベル)、^routine (指定した外部ルーチンの先頭)、または label^routine (指定した外部ルーチンの指定したラベル) として指定できます。
$ETRAP は、一部のコンテキスト (プロシージャ以外) で label+offset をサポートしています。オプションのこの +offset は、label からオフセットする行数を指定する整数です。インターシステムズでは、エラー・ハンドラの場所の指定時には行のオフセットを使用しないことを推奨します。
$ETRAP の cmdline 文字列値が実行可能 ObjectScript コマンドであるため、文字列の長さを ObjectScript ルーチン行の最大長さ (32,741 文字) より長くすることはできません。$ETRAP をこれより長い文字列に設定すると、<MAXSTRING> エラーになる可能性があります。cmdline 文字列の指定の詳細は、"XECUTE" コマンドを参照してください。
$ETRAP を新しい値に設定する前の NEW の使用
NEW コマンドで最初に $ETRAP の新しいコピーを作成しないコンテキストで、新しい値を $ETRAP に割り当てる場合、InterSystems IRIS は、現在のコンテキストだけでなく、前のすべてのコンテキストにも、その新しい値を $ETRAP の値として設定します。したがって、新しい値で $ETRAP を設定する前に、NEW $ETRAP コマンドを使用して $ETRAP の新しいコピーを作成することを強くお勧めします。
XECUTE コマンドと比較した $ETRAP コマンド
$ETRAP 文字列内のコマンドは、XECUTE 文字列でのコマンドとは異なり、新しいコンテキスト・レベルでは実行されません。また、$ETRAP コマンド文字列は、常に暗黙的な QUIT コマンドにより終了されます。引数付きの QUIT コマンドを必要とするユーザ定義の関数のコンテキストで $ETRAP エラー処理コマンドが呼び出されると、暗黙的な QUIT コマンドは NULL 文字列の引数で終了します。
異なるコンテキスト・レベルでの $ETRAP 値の設定
InterSystems IRIS は、既定では、$ETRAP 特殊変数の値を新しい DO、XECUTE、およびユーザ定義関数コンテキストに伝送します。しかし、以下のように、NEW コマンドを発行することで、コンテキストで $ETRAP の新しいコピーを作成できます。
NEW $ETRAP
$ETRAP に対して NEW を発行すると、InterSystems IRIS は必ず次のアクションを実行します。
-
その時点で使用中の $ETRAP のコピーを保存します。
-
$ETRAP の新しいコピーを作成します。
-
$ETRAP の新しいコピーに、保存されている古い $ETRAP のコピーと同じ値を割り当てます。
ユーザは、その後、SET コマンドを使用して、$ETRAP の新しいコピーに別の値を割り当てます。このようにして、現在のコンテキストで新しい $ETRAP エラー処理コマンドを設定できます。
NULL 文字列に設定することで、$ETRAP をクリアすることもできます。その後、InterSystems IRIS は、エラーの発生するイベントのコンテキスト・レベルで $ETRAP コマンドを実行しなくなります。
QUIT コマンドにより現在のコンテキストが終了されると、InterSystems IRIS は、保存されている古い $ETRAP の値をリストアします。
例
以下の例では $ETRAP または $ZTRAP を使用して同じ操作を実行します。<DIVIDE> エラーが発生したら、ErrMod に進みます。$RANDOM 関数はランダムにいずれかのエラー・ハンドラを呼び出します。
MainMod
WRITE "MainMod stack:",$STACK,!
SET x=$RANDOM(2)
IF x=0 {WRITE "$ETRAP",!
NEW $ETRAP
SET $ETRAP="GOTO ErrMod"
WRITE 5/0}
IF x=1 {WRITE "$ZTRAP",!
SET $ZTRAP="ErrMod"
WRITE 5/0}
QUIT
ModuleA
/* code not executed */
QUIT
ErrMod
WRITE !,"in ErrMod",!
WRITE "ErrMod stack:",$STACK
QUIT
以下の例では、$ETRAP の値を新しいコンテキストに伝送する方法、およびエラーの発生後に各コンテキストで再度 $ETRAP エラー処理コマンドを呼び出す方法を示します。この例の $ETRAP コマンドは、エラーの破棄を試みません。むしろ、既定で制御が前の各コンテキスト・レベルの $ETRAP エラー処理コマンドに返されます。
サンプル・コードは以下のとおりです。
ETR
NEW $ETRAP
SET $ETRAP="WRITE !,""$ETRAP invoked at Context Level "",$STACK"
; Initiate an XECUTE context that initiates a DO context
XECUTE "DO A"
QUIT
; Initiate a user-defined function context
A
WRITE "In A",!
SET A=$$B
QUIT
B()
; User-defined function that generates an error
WRITE "In B",!
WRITE "impossible division ",5/0
QUIT 1
このコードを使用したサンプルの Terminal セッションは、次のように実行されます。
USER>DO ^ETR
In A
In B
impossible division
$ETRAP invoked at context level 4
$ETRAP invoked at context level 3
$ETRAP invoked at context level 2
$ETRAP invoked at context level 1
USER>
$ETRAP とその他の ObjectScript エラー処理機能
$ETRAP 特殊変数は、アプリケーションで発生するエラーの処理およびログ記録の制御を可能にする、いくつかの ObjectScript 言語機能の 1 つです。
-
エラー処理で推奨する InterSystems IRIS の機能は、ブロック構造の TRY および CATCH コマンドです。
-
$ZTRAP 特殊変数は、$ETRAP よりもお勧めです。
-
$ETRAP は、InterSystems IRIS で引き続きサポートされます。しかし、一般的には、新しいコードで $ETRAP を他のエラー処理機能より優先して使用することは避けてください。
エラー処理の詳細は、"TRY-CATCH の使用法" を参照してください。
$ETRAP と $ZTRAP
$ZTRAP を使用してエラー・ハンドラを設定する場合、このハンドラは既存のどの $ETRAP エラー・ハンドラよりも優先されます。InterSystems IRIS は暗黙的に NEW $ETRAP コマンドを実行し、$ETRAP を NULL 文字列 ("") に設定します。
$ETRAP および TRY / CATCH
TRY コマンドと CATCH コマンドは実行レベル内でエラー処理を行います。TRY ブロック内で例外が発生すると、InterSystems IRIS は通常、TRY ブロックの直後に続く例外処理コードの CATCH ブロックを実行します。
TRY ブロックで構成されたプログラム内では $ETRAP を使用しないことを強くお勧めします。
TRY ブロック内で $ETRAP を設定することはできません。これを試みると、コンパイル・エラーが生成されます。$ETRAP は、TRY ブロックの前、または CATCH ブロック内で設定できます。
以前に $ETRAP が設定されており、TRY ブロックで例外が発生した場合、InterSystems IRIS はこの可能性を予想していない限り、CATCH ではなく $ETRAP を取得します。$ETRAP と CATCH の両方が存在する場合、InterSystems IRIS は現在の実行レベルに適用されるエラー・コード (CATCH または $ETRAP) を実行します。$ETRAP は本来実行レベルとは関連付けられないため、InterSystems IRIS では、他に指定されていない限り現在の実行レベルに関連付けられていると見なします。$ETRAP を設定して $ETRAP のレベル・マーカを設定する前に、NEW $ETRAP を実行して、InterSystems IRIS が現在のレベルの例外ハンドラとして $ETRAP ではなく CATCH を取得するようにする必要があります。そうしないと、システム・エラー (THROW コマンドによりスローされるシステム・エラーを含む) により $ETRAP 例外ハンドラが取得される可能性があります。
CATCH ブロック内で発生する例外は、現在のエラー・トラップ・ハンドラによって処理されます。