Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

$ZTRAP (ObjectScript)

現在のエラー・トラップ・ハンドラの場所が含まれます。

Synopsis

$ZTRAP 
$ZT

説明

$ZTRAP には、現在のエラー・トラップ・ハンドラの場所が含まれます。エラー・トラップ・ハンドラをコード化する方法の詳細は、"ObjectScript の使用法" の “エラー処理” の章にある “$ZTRAP でのエラー処理” を参照してください。

  • ルーチンでは、$ZTRAP はそのルーチンまたは他のルーチン内のラベルを参照できます。これには、ラベル名とルーチン名が含まれます。例えば、ルーチン MyRou 内の ラベル MyHandler に $ZTRAP を設定した場合、$ZTRAP 特殊変数には MyHandler^MyRou が含まれます。

  • プロシージャでは、$ZTRAP はそのプロシージャ内のラベルを参照する必要があります。これには、プロシージャ名からのラベルの行オフセットが含まれます。例えば、プロシージャ MyProc 内のプライベート・ラベル MyHandler に $ZTRAP を設定した場合、$ZTRAP 特殊変数には +17^MyProc が含まれます。

$ZTRAP を設定するには、次の 3 つの方法があります。

KILL $ZTRAP を実行することはできません。これを実行しようとすると、<SYNTAX> エラーになります。現在の $ZTRAP 値を削除するには、$ZTRAP="" を指定します。

Location

SET コマンドを使用することで、引用符付きの文字列として location を指定できます。

  • ルーチンでは、locationlabel (現在のルーチン内の行ラベル)、^routine (指定された外部ルーチンの開始)、または label^routine (指定された外部ルーチン内の指定されたラベル) として指定できます。プロシージャ内のラベルやプロシージャを参照する location をルーチンで指定しないでください。これは無効な location であり、InterSystems IRIS が $ZTRAP を実行しようとする際に実行時エラーになります。

  • プロシージャでは、label (そのプロシージャ・ブロック内のプライベート・ラベル) として location を指定できます。プロシージャ・ブロック内の $ZTRAP は、プロシージャ本体の外側にある location への移動には使用できません。プロシージャ・ブロック内の $ZTRAP は、プロシージャ・ブロック内の location しか参照できません。したがって、プロシージャでは、$ZTRAP^routinelabel^routine に設定することはできません。設定しようとすると、<SYNTAX> エラーになります。

    プロシージャでは $ZTRAP をプライベート・ラベル名に設定しますが、$ZTRAP 値はプライベート・ラベル名ではなく、プロシージャ・ラベル (プロシージャの先頭) からプライベート・ラベルの行の場所までのオフセットです。(例) +17^myproc

Note:

$ZTRAP は、一部のコンテキスト (プロシージャ以外) で label+offset に対する従来のサポートを提供します。オプションのこの +offset は、label からオフセットする行数を指定する整数です。label は、同じルーチンに含める必要があります。+offset の使用は非推奨であり、コンパイル警告エラーが発生する場合があります。インターシステムズでは、location の指定時には行のオフセットを使用しないことを推奨します。

プロシージャまたは IRISSYS % ルーチンの呼び出し時における +offset の指定はできません。指定しようとすると、InterSystems IRIS は <NOLINE> エラーを発行します。

$ZTRAPlocation は、現在のネームスペースにある必要があります。$ZTRAP では、拡張ルーチン参照をサポートしません。

存在しない行ラベル (現在のルーチンに存在しない location) を指定した場合、以下が発生します。

  • $ZTRAP の表示 : ルーチンでは、$ZTRAP には label^routine が含まれます。(例) DummyLabel^MyRou。プロシージャでは、$ZTRAP にはオフセットの最大許容値が含まれます。(例) +34463^MyProc

  • $ZTRAP の呼び出し : InterSystems IRIS が <NOLINE> エラー・メッセージを返します。

各スタック・レベルは専用の$ZTRAP 値を備えることができます。$ZTRAP を設定すると、システムでは前回のスタック・レベルの $ZTRAP 値が保存されます。InterSystems IRIS では、現在のスタック・レベルが終了すると、この値がリストアされます。現在のスタック・レベルでエラー・トラップをオンにするには、エラー・トラップ・ハンドラの location を指定して、$ZTRAP にエラー・トラップ・ハンドラを設定します。次に例を示します。

   IF $ZTRAP="" {WRITE !,"$ZTRAP not set" }
   ELSE {WRITE !,"$ZTRAP already set: ",$ZTRAP
         SET oldtrap=$ZTRAP }
   SET $ZTRAP="Etrap1^Handler"
   WRITE !,"$ZTRAP set to: ",$ZTRAP
   //  program code
   SET $ZTRAP=oldtrap
   WRITE !,"$ZTRAP restored to: ",$ZTRAP

エラーが発生すると、この形式ではコール・スタックが戻され、特定のエラー・トラップ・ハンドラに制御が移されます。

SqlComputeCode では、$ZTRAP=$ZTRAP を設定しないでください。これは、トランザクション処理およびエラー報告に関する重大な問題を引き起こす可能性があります。

エラー・トラップをオフにするには、$ZTRAP を NULL 文字列 ("") に設定します。これを行うと、現在 DO が実行されているスタック・レベルに設定されているエラー・トラップをクリアします。

$ZTRAP を使用してエラー・ハンドラを設定する場合、このハンドラは既存のどの $ETRAP エラー・ハンドラよりも優先されます。InterSystems IRIS は暗黙的に NEW $ETRAP コマンドを実行し、$ETRAP を NULL 文字列 ("") に設定します。

Note:

ターミナル・プロンプトからの $ZTRAP の使用は、現在のコード行に制限されます。SET $ZTRAP コマンドと、エラーを生成するコマンドは、コードの同じ行に含まれている必要があります。ターミナルは、各コマンド行の先頭で $ZTRAP をシステムの既定値にリストアします。

*Location

ルーチンでは、エラーが発生した後、コール・スタックをそのままにしておくこともできます。これを行うには、location の前および二重引用符内にアスタリスク (*) を挿入します。プロシージャ内でこの形式を使用することは有効ではありません。これを使用しようとすると、<SYNTAX> エラーになります。この例に示すように、プロシージャではないサブルーチンでのみ使用できます。

Main
   SET $ZTRAP="*OnError"
   WRITE !,"$ZTRAP set to: ",$ZTRAP
  // program code
OnError
   // Error handling code
   QUIT

この形式では、$ZTRAP で指定した行ラベルへの GOTO が実行されるだけです。$STACK$ESTACK は変更されません。$ZTRAP エラー処理ルーチンのコンテキスト・フレームは、エラーが発生したコンテキスト・フレームと同じです。ただし、InterSystems IRIS は $ROLES を、$ZTRAP が設定されていた実行レベルに有効であった値にリセットします。これにより $ZTRAP エラー・ハンドラは、エラー・ハンドラの設定後にルーチンに付与された上位特権を使用しないようにします。$ZTRAP エラー処理ルーチンが完了すると、スタックが前のコンテキスト・レベルに戻されます。この形式の $ZTRAP は特に、予期しないエラーの分析に便利です。

アスタリスクによって $ZTRAP オプションが設定されます。これは、location の一部ではありません。そのため、$ZTRAPWRITE または ZZDUMP を実行しても、このアスタリスクは表示されません。

^%ETN

ルーチンでは、SET $ZTRAP="^%ETN" は、現在のエラー・トラップ・ハンドラとして、システムで提供されるエラー・ルーチン %ETN を設定します。%ETN は、これを呼び出したエラーの発生元であるコンテキストで実行されます。(%ET%ETN の従来の名前です。これらの機能は同じですが、%ETN のほうが多少効率性に優れています)。エラー・ハンドラ ^%ETN は常に、* (アスタリスク) が先行しているかのように動作します。

プロシージャ・ブロック内の $ZTRAP は、プロシージャ本体の外側にある location への移動には使用できないため、プロシージャで SET $ZTRAP="^%ETN" を使用することはできません。使用しようとすると、<SYNTAX> エラーが返されます。

%ETN およびそのエントリ・ポイント FORE^%ETN、BACK^%ETN、および LOG^%ETN の詳細は、"ObjectScript の使用法" の “エラー処理” の章にある “アプリケーション・エラーのログ作成” のセクションを参照してください。

TRY / CATCH と $ZTRAP

TRY ブロック内で $ZTRAP を設定することはできません。これを試みると、コンパイル・エラーが生成されます。$ZTRAP は、TRY ブロックの前、または CATCH ブロック内で設定できます。

TRY ブロック内で発生したエラーは、$ZTRAP が以前に設定されているかどうかに関係なく、CATCH ブロックで処理されます。CATCH ブロック内で発生するエラーは、現在のエラー・トラップ・ハンドラによって処理されます。

以下の最初の例では、TRY ブロックで発生したエラーを示します。以下の 2 番目の例では、TRY ブロックにスローされた例外を示します。以下の両方の場合において、$ZTRAP ではなく、CATCH ブロックが用いられています。

  SET $ZTRAP="Ztrap"
  TRY { WRITE 1/0 }    /* divide-by-zero error */
  CATCH { WRITE "Catch taken" }
  QUIT
Ztrap
  WRITE "$ZTRAP taken"
  SET $ZTRAP=""
  QUIT
  SET $ZTRAP="Ztrap"
  TRY { SET myvar=##class(Sample.MyException).%New("Example Error",999,,errdatazero)
        WRITE !,"Throwing an exception!",!
        THROW myvar
        QUIT  }
  CATCH { WRITE "Catch taken" }
  QUIT
Ztrap
  WRITE "$ZTRAP taken"
  SET $ZTRAP=""
  QUIT

ただし、TRY ブロックは $ZTRAP を設定および使用するコードを呼び出すことができます。以下の例では、0 による除算エラーが CATCH ブロックではなく、$ZTRAP によりキャッチされています。

  TRY { DO Errsub } 
  CATCH { WRITE "Catch taken" }
  QUIT
Errsub
  SET $ZTRAP="Ztrap"
  WRITE 1/0   /* divide-by-zero error */
  QUIT
Ztrap
  WRITE "$ZTRAP taken"
  SET $ZTRAP=""
  QUIT

CATCH ブロックからの THROW コマンドでも、$ZTRAP エラー・ハンドラを呼び出すことができます。

次の例では、$ZTRAP がこのプログラムの OnError ルーチンに設定されます。これによって、(数値を 0 で除算しようとすると) エラーが発生する SubA が呼び出されます。エラーが発生すると、$ZTRAP で指定した OnError ルーチンが呼び出されます。OnError は、$ZTRAP が設定されたコンテキスト・レベルで呼び出されます。OnError は Main と同じコンテキスト・レベルにあるため、実行は Main に戻りません。

Main
   NEW $ESTACK
   SET $ZTRAP="OnError"
   WRITE !,"$ZTRAP set to: ",$ZTRAP
   WRITE !,"Main $ESTACK= ",$ESTACK   // 0
   WRITE !,"Main $ECODE= ",$ECODE
   DO SubA
   WRITE !,"Returned from SubA"   // not executed
   WRITE !,"MainReturn $ECODE= ",$ECODE
   QUIT
SubA
   WRITE !,"SubA $ESTACK= ",$ESTACK   // 1
   WRITE !,6/0    // Error: division by zero
   WRITE !,"fine with me"
   QUIT
OnError
   WRITE !,"OnError $ESTACK= ",$ESTACK   // 0
   WRITE !,"$ECODE= ",$ECODE
   QUIT

次の例は、1 つの例外を除き、前の例と同じです。つまり、$ZTRAP location がアスタリスク (*) で始まっています。SubA でエラーが発生すると、このアスタリスクによって、($ZTRAP が設定された) Main のコンテキスト・レベルではなく、(エラーが発生した) SubA のコンテキスト・レベルで OnError ルーチンが呼び出されます。そのため、OnError が完了すると、DO コマンドに続く行で実行が Main に戻ります。

Main
   NEW $ESTACK
   SET $ZTRAP="*OnError"
   WRITE !,"$ZTRAP set to: ",$ZTRAP
   WRITE !,"Main $ESTACK= ",$ESTACK   // 0
   WRITE !,"Main $ECODE= ",$ECODE
   DO SubA
   WRITE !,"Returned from SubA"   // executed
   WRITE !,"MainReturn $ECODE= ",$ECODE
   QUIT
SubA
   WRITE !,"SubA $ESTACK= ",$ESTACK   // 1
   WRITE !,6/0    // Error: division by zero
   WRITE !,"fine with me"
   QUIT
OnError
   WRITE !,"OnError $ESTACK= ",$ESTACK   // 1
   WRITE !,"$ECODE= ",$ECODE
   QUIT

関連項目

FeedbackOpens in a new tab