例外処理

EGL 生成のプログラムが次のような動作を行うと、エラーが発生することがあります。

try ブロック

EGL try ブロック は、tryend の区切り文字に挟まれた多くの EGL 文に対するゼロの系列です。 以下に例を示します。
  if (userRequest = "A")
    try
      add record1;
    onException
      myErrorHandler(12);
    end
  end

一般に、try ブロックによって、エラーが生じた場合でもプログラムで処理を継続することができます。

try ブロックには、以前に示した onException 文節 が含まれていることがあります。この文節は、try ブロック内の以前の文のいずれかが失敗した場合に呼び出されますが、onException 文節がない場合は、try ブロック内のエラーによって、その try ブロックの直後の最初の文が呼び出されます。

システム例外

EGL は、実行時の問題について特定の性質を示すために、一連のシステム例外を備えています。 これらの例外は、それぞれが 1 つの辞書になっており、そこから情報を取り出すことができますが、取り出しには、常にシステム変数 SysLib.currentException (これも辞書) を使用します。この変数により、実行単位内でスローされた最新の例外にアクセスできます。

どの例外にも、code という 1 つのフィールドがあり、これは、その例外を識別するストリングです。 このフィールドを次のようにロジック内でテストすることにより、現行の例外を判別できます。
  if (userRequest = "A")
    try
      add record1;
    onException
      case (SysLib.currentException.code)
        when (FileIOException)
          myErrorHandler(12);
        otherwise
          myErrorHandler(15);
      end
    end
  end

この場合、FileIOException は「com.ibm.egl.FileIOException」というストリング値に相当する定数です。 EGL 例外定数は常に、「com.ibm.egl」で始まるストリング内の最後の修飾子と等価です。

例外フィールドへのアクセスは、onException ブロック内でのみ行うことを強くお勧めします。 例外が発生しなかったときに、コードが SysLib.currentException にアクセスすると、実行単位は終了します。

次の例は、例外 SQLException 内の sqlcode フィールドにアクセスします。
  if (userRequest = "A")
    try
      add record01;
    onException
      case (SysLib.currentException.code)
        when ("com.ibm.egl.SQLException")
          if (SysLib.currentException.sqlcode == -270)
            myErrorHandler(16);
          else
            myErrorHandler(20);
          end
        otherwise
          myErrorHandler(15);
      end
    end
  end

システム例外の詳細については、『EGL システム例外』を参照してください。

try ブロックの制限

以前の try ブロックについての詳細は、限定される必要があります。まず、try ブロックは、以下の種類の EGL 文でのエラー処理にのみ影響します。
  • I/O 文
  • システム関数
  • call 文

try ブロックの存在によって、数値オーバーフローの処理が影響を受けることはありません。この種のエラーの詳細については、『VGVar.handleOverflow』を参照してください。

第 2 に、try ブロックは、try ブロック内部から呼び出されたユーザー関数 (またはプログラム) 内のエラーに影響を与えません。次の例では、文が関数 myABC で失敗すると、関数 myABC が自らエラーを処理する場合を除いて、プログラムはエラー・メッセージとともに即時に終了します。
  if (userRequest = "B")
    try
      myVariable = myABC();
    onException
      myErrorHandler(12);
    end
  end
第 3 に、プログラムは即時に終了し、以下のような場合にエラー・メッセージが表示されます。
  • try ブロックによって明確にカバーされた種類のエラーが、try ブロックの外部で生じる
  • 以下の場合のいずれかが当てはまる場合 (try ブロック内も含む)
    • ユーザー作成関数が、呼び出し時または呼び出し側への戻り時に失敗する
    • ファイルまたは MQSeries® I/O 文がハード・エラー (後に説明) で終了したときに、システム変数 VGVar.handleHardIOErrors に 0 が設定されている
    • IMS™ キューまたは DL/I データベースにアクセスする試みがハード・エラーで終了したときに、システム変数 DLIVar.handleHardDLIErrorsVGVar.handleHardIOErrors の両方に 0 が設定されている
以下の場合も該当します。
  • 値がゼロで割られると、Java™ プログラムではこの状況が数値オーバーフローとして処理されます。
  • 数値変数に非数値文字が代入されると、Java プログラムは終了します。
VisualAge® Generator および EGL 5.0 で作成されたプログラムのマイグレーションをサポートするために、変数 VGVar.handleSysLibraryErrors (旧名 EZEREPLY) は、try ブロックの外側で生じるいくつかのエラーを処理することができます。この変数は使用しないでください。この変数が機能するのは VisualAge Generator 互換モードの場合のみです。

エラー関連システム変数

EGL は、正常なイベントの応答または終了しないエラーの応答として、try ブロックに設定されたエラー関連システム変数を提供します。これらの変数の値は、try ブロック内およびその try ブロックに後続して実行されるコード内で使用でき、大抵の場合、値は変換後にリストアされます。

try ブロック内では、以下の規則が適用されます。
  • システム変数 sysVar.errorCode には、以下の種類の文のいずれかが実行された後に値が提供されます。
    • call
    • 索引ファイル、MQ ファイル、相対ファイル、またはシリアル・ファイルに対する I/O 文
    • ほとんどすべてのシステム関数の呼び出し
  • I/O 文が MQ レコード上で作動した後、システム変数 sysVar.errorCodeVGVar.mqConditionCode に値が提供されます。
  • try ブロック内で、リレーショナル・データベースにアクセスがあった後、SQL 通信域 (SQLCA) の変数に値が割り当てられます。詳しくは、SysVar.sqlca を参照してください。
  • DL/I データベースにアクセスがあった後、PCB 状況変数 (DLIVar.dbNameDLIVar.keyAreaDLIVar.keyAreaLenDLIVar.segmentLevelDLIVar.procOptionsDLIVar.segmentNameDLIVar.numSensitiveSegs、および DLIVar.statusCode) に値が割り当てられます。

    CICS® で稼動中の場合、値は CICS DL/I 状況変数 (DLIVar.cicsErrorDLIVar.cicsCondition、および DLIVar.cicsRestart) にも割り当てられます。

EGL ランタイムは、コードが GSAM ファイルにアクセスした後、または IMS メッセージ・キュー・アクセスの後は、先にリストした DL/I 関連の変数を設定しません。そのアクセスはシリアル・ファイル・アクセスと見なされます。それらの事例で、追加の状況情報へのアクセスを取得するには、適切な PCB レコードを使用します。概要については、『ランタイム PSB および PCB の EGL サポート』を参照してください。PCB レコードの特定のタイプについての詳細は、『レコード・タイプとプロパティー』を参照してください。

エラー・コードは、『VGVar.handleOverflow』の説明にあるように、無限の数値オーバーフローの場合、sysVar.errorCode に割り当てられます。しかし、正常な算術計算がエラー関連システム変数に影響を与えることはありません。

また、エラー関連システム変数は、システム関数以外の関数の呼び出しによって影響を受けません。そして、sysVar.errorCode (大抵のシステム関数によって影響を受ける変数) は、以下の変数でのエラーによって影響を受けません。
  • sysLib.calculateChkDigitMod10
  • sysLib.calculateChkDigitMod11
  • strLib.concatenate
  • strLib.concatenateWithSeparator
  • VGLib.concatenateBytes
  • VGLib.connectionService
  • sysLib.connect
  • sysLib.convert
  • sysLib.disconnect
  • sysLib.disconnectAll
  • sysLib.purge
  • sysLib.queryCurrentDatabase
  • strLib.setBlankTerminator
  • sysLib.setCurrentDatabase
  • strLib.strLen
  • sysLib.verifyChkDigitMod10
  • sysLib.verifyChkDigitMod11
  • sysLib.wait

EGL ランタイムは、文が試行ブロックの外部で実行されるときに、エラー関連変数の値を変更しません。ただし、ユーザーのプログラムは、try ブロック外部のエラー関連変数に値を割り当てることができます。

I/O 文

I/O 文に関して、エラーはハードかソフトのいずれかです。
  • ソフト・エラーは、以下のいずれかです。
    • SQL データベース・テーブルに対する入出力 (I/O) 操作時にレコードが見付からない
    • 索引付きファイル、相対ファイル、シリアル・ファイルの入出力 (I/O) 操作、または DL/I セグメントでの入出力 (I/O) 操作、または DL/I アクセスにおける入出力 (I/O) 操作で以下のいずれかの問題が発生する
      • 重複レコード (外部データ・ストアが重複の追加を許可する場合) 同等 DL/I 状況コードは、II です。
      • レコードが見付からない。同等 DL/I 状況コードは GE で、同等 IMS メッセージ・キューの状況コードは、QD です。
      • ファイルの終わり。同等 DL/I または GSAM 状況コードは GB で、同等 IMS メッセージ・キュー状況コードは QC です。
  • ほとんどの事例で、ハード・エラーがその他の問題になります。例えば次のようなエラーです。
    • 重複レコード (外部データ・ストアが重複の追加を禁止する場合)
    • ファイルが見つからない
    • データ・セットのリモート・アクセス時に通信リンクが使用できない

    DL/I との関係では、GA、GB、GD、GE、GK、または II 以外の非ブランク状況コードは、ハード・エラーです。GSAM との関係では、GB 以外の非ブランク状況コードは、ハード・エラーです。 IMS との関係では、QC、QD、CE、CF、 CG、CI、CJ、CK、または CL 以外の非ブランク状況コードはハード・エラーです。

ソフト・エラーの原因となった文が try ブロック内にある場合は、以下のことが当てはまります。
  • デフォルトでは、EGL は onException ブロックに制御を渡さず、実行を続行します。
  • OnException ブロックに制御を渡したい場合は、プログラム、pageHandler、またはライブラリーの中で、throwNrfEofExceptions プロパティーを yes に設定します。
ハード入出力エラーが try ブロックで生じた場合は、結果は、エラー関連システム変数の値によって決まります。
  • ファイル、リレーショナル・データベース、または MQSeries メッセージ・キューへのアクセス時には、以下の規則が適用されます。
    • sysVar.handleHardIOErrors が 1 に設定されていれば、プログラムは実行を続ける
    • sysVar.handleHardIOErrors が 0 に設定されていれば、プログラムは (可能な場合) エラー・メッセージを表示して、終了する

    この変数のデフォルト設定は、handleHardIOErrors プロパティーの値によって異なり、このプロパティーは、プログラム、ライブラリー、pageHandler などの生成可能ロジック・パーツの中で使用可能です。 このプロパティーのデフォルト値は yes で、これは、変数 sysVar.handleHardIOErrors の初期値を 1 に設定します。

  • IMS キューまたは DL/I データベースへのアクセス時には、以下の規則が適用されます。
    • VGVar.handleHardIOErrors または DLIVar.handleHardDLIErrors が 1 に設定されている場合、プログラムは実行を続行する
    • VGVar.handleHardIOErrors または DLIVar.handleHardDLIErrors が 0 に設定されている場合、プログラムは (可能な場合) エラー・メッセージを表示して終了する

ハードまたはソフトのいずれかの入出力エラーが try ブロック外部で生じた場合、生成したプログラムは可能な場合はエラー・メッセージを提示してから、終了します。

DB2® に直接アクセスしている場合 (JDBC 経由でなく)、ハード・エラーの sqlcode は 304、802、または 0 より小さい値です。

エラーの識別

try ブロックの内部または外部に case または if 文を組み込むことによって、try ブロック内で生じたエラーの種類を判別できます。その文内では、さまざまなシステム変数の値をテストすることができます。ただし、入出力エラーに応答している場合、および文で EGL レコードを使用している場合は、基本論理式の使用が推奨されます。式の形式には、次の 2 種類があります。
  recordName is IOerrorValue

  recordName not IOerrorValue
recordName
入出力操作で使用されたレコードの名前。
IOerrorValue
データベース管理システム全体で一定の入出力エラー値の 1 つ。

入出力エラー値が指定された論理式を使用しないでデータベース管理システムを変更する場合は、プログラムの変更と再生成が必要になることがあります。特に、sysVar.sqlcode または sysVar.sqlState 内の同等の値ではなく、入出力エラー値を使用して、エラーの有無をテストすることをお勧めします。、それらの値は、基盤となるデータベース実装によって異なります。

フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.