例外処理

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 システム例外

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 ブロック内も含む)
    • ユーザー作成関数の呼び出しまたは戻り時に、障害が生じる
    • 数値変数に非数値文字が割り当てられている
    • ファイル I/O 文がハード・エラー (後に説明) で終了したときに、システム変数 VGVar.handleHardIOErrors に 1 でなく 0 が設定されている
  • 以下の場合のいずれかが当てはまる場合 (try ブロック内も含む)
    • ユーザー作成関数が、呼び出し時または呼び出し側への戻り時に失敗する
    • ファイルまたは MQSeries® I/O 文がハード・エラー (後に説明) で終了したときに、システム変数 VGVar.handleHardIOErrors に 0 が設定されている
    • IMS™ キューまたは DL/I データベースにアクセスする試みがハード・エラー (後に説明) で終了したときに、システム変数 VGVar.handleHardDLIErrorsVGVar.handleHardIOErrors の両方に 0 が設定されている
以下の場合も該当します。
  • 値がゼロで割られると、COBOL 実行単位は終了します (Java™ プログラムでは、そうした状況は数値オーバーフローとして処理されます)
  • 値がゼロで割られると、Java プログラムではこの状況が数値オーバーフローとして処理されます。
  • 数値変数に非数値文字が代入されると、COBOL 実行単位または Java プログラムは終了します。(ビルド記述子オプション spacesZero を指定して生成を実行すると、COBOL プログラムは保護を獲得します)
注: VisualAge® Generator および EGL 5.0 で作成されたプログラムのマイグレーションをサポートするために、変数 VGVar.handleSysLibraryErrors (旧名 ezereply) は、try ブロックの外側で生じるいくつかのエラーを処理することができます。 この変数は使用しないでください。この変数が機能するのは VisualAge Generator との互換性モードの場合のみです。

エラー関連システム変数

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

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

システム変数 sysVar.exceptionCode には、さまざまな状態の値が与えられます。そして、それらのすべての状態において、ランタイム環境とのプログラムの相互作用の性質に応じて、1 つ以上の追加の変数も設定されます。
  • システム変数 sysVar.exceptionCode および sysVar.errorCode には、両方ともに、以下の種類の任意の文を try ブロックで実行した後に、値が与えられます。
    • call
    • 索引ファイル、MQ ファイル、相対ファイル、またはシリアル・ファイルに対する I/O 文
    • ほとんどすべてのシステム関数の呼び出し
  • システム変数 sysVar.exceptionCodesysVar.errorCodeVGVar.mqConditionCode、および sysVar.mqReasonCode のすべてには、try ブロック内の I/O 文が MQ レコード上で作動した後に値が与えられます。
  • システム変数 sysVar.exceptionCode には、try ブロック内の文からリレーショナル・データベースにアクセスした後に、値が与えられます。SQL 通信域 (SQLCA) の 変数にも値が割り当てられます (詳細については sysVar.sqlca を参照)。
  • 最後に、システム変数 sysVar.exceptionCode および さまざまな DL/I 関連変数にはすべて、IMS キューまたは DL/I データベースに try ブロック内の文からアクセスした後に、値が与えられます。

try ブロック内で無限のエラーが生じた場合、sysVar.exceptionCode の値は、エラーが try ブロックの外部で生じた場合にユーザーに提示される EGL エラー・メッセージの数値コンポーネントと同一の値です。ただし、sysVar.errorCodeVGVar.mqConditionCode など、状態固有の変数の値は、ランタイム・システムによって提供されます。 エラーがない場合、sysVar.exceptionCode の値と、少なくとも 1 つの状態特定変数とは、同じ 8 つのゼロのストリングです。

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

また、エラー関連システム変数は、システム関数以外の関数の呼び出しによって影響を受けません。そして、sysVar.errorCode (大抵のシステム関数によって影響を受ける変数) は、以下の変数でのエラーによって影響を受けません。
  • sysLib.calculateChkDigitMod10
  • sysLib.calculateChkDigitMod11
  • strLib.concatenate
  • strLib.concatenateWithSeparator
  • 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

エラー値が sysVar.exceptionCode に割り当てられた場合、 システム変数 sysVar.exceptionMsg には関連した EGL エラー・メッセージのテキストが割り当てられ、システム変数 sysVar.exceptionMsgCount には エラー・メッセージ内のバイト数 (末尾ブランクおよび NULL を除く) が割り当てられます。8 つのゼロのストリングが sysVar.exceptionCode に割り当てられた場合、sysVar.exceptionMsg はブランクが割り当てられ、sysVar.exceptionMsgCount はゼロに設定されます。

I/O 文

I/O 文に関して、エラーはハードかソフトのいずれかです。
  • ソフト・エラーは、以下のいずれかです。
    • SQL データベース表または DL/I セグメントに対する入出力 (I/O) 操作時にレコードが見付からない
    • 索引付きファイル、相対ファイル、またはシリアル・ファイルの入出力 (I/O) 操作で、 以下のいずれかの問題が発生する
      • 重複レコード (外部データ・ストアが重複の追加を許可する場合)
      • レコードが見付からない
      • ファイル終わり
  • ハード・エラー。その他の問題であり、例えば次のようなエラーです。
    • 重複レコード (外部データ・ストアが重複の追加を禁止する場合)
    • ファイルが見つからない
    • データ・セットのリモート・アクセス時に通信リンクが使用できない
ソフト・エラーの原因となった文が try ブロック内にある場合は、以下のことが当てはまります。
  • デフォルトでは、EGL は onException ブロックに制御を渡さず、実行を続行します。
  • OnException ブロックに制御を渡したい場合は、プログラム、pageHandler、またはライブラリーの中で、throwNrfEofExceptions プロパティーを yes に設定します。
ハード入出力エラーが try ブロックで生じた場合は、結果は、エラー関連システム変数の値によって決まります。
  • ファイル、リレーショナル・データベース、または MQSeries メッセージ・キューへのアクセス時には、以下の規則が適用されます。
    • VGVar.handleHardIOErrors が 1 に設定されていれば、プログラムは実行を続行する
    • VGVar.handleHardIOErrors が 0 に設定されていれば、プログラムは (可能な場合) エラー・メッセージを表示して終了する

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

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

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

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

エラーの識別

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

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

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

ご利用条件 | フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.(C) Copyright IBM Japan 2005.