エラーの処理
EGL を使用すると、エラーの場合のプログラムの動作を決定することができます。
エラーの処理とは、プログラムで発生する可能性のある問題の種類を予想し、それぞれについてコードのパスを提供することです。 エラーを処理しない場合、無視できる範囲のもの (このトピックで後述する『入出力エラー』を参照) を除き、エラーの発生したプログラムはすべて強制終了されます。
- messageID
- その例外の EGL メッセージを含むストリングです。例えば、初期化されていない配列を使用しようとすると、EGL は NullValueException レコードの messageID を EGL0106E に設定します。
- message
- その問題の簡単な説明を含むストリングです。例えば、messageID が EGL0106E の場合 message は、「NULL 参照が使用されました。」です。
例外レコードには、必要に応じて追加のフィールドを含めることができます。例えば、IndexOutOfBoundsException には、indexValue の追加フィールドがあり、EGL が処理できなかった配列添字の値が含まれます。
try ブロック
onException(myEx NullValueException)
try
intArray[10] = 0; // これは初期化されていない場合があります
onException(myEx NullValueException)
writeStdErr(myEx);
myErrorHandler(myEx);
end
myErrorHandler() 関数は、例えば、配列を初期化してから、もう一度代入を行います。
try
get next mySerialRecord
onException(myEx AnyException)
myErrorHandler(myEx);
end
try
get next mySerialRecord
onException(myEx FileIOException)
myErrorHandler1(myEx);
onException(myEx AnyException)
myErrorHandler2(myEx);
end
myErrorHandler2() は FileIOException 以外のすべての例外を処理します。
EGL が例外をスローしても、その例外をキャッチする onException ブロックがない場合、関数は直ちに終了し、エラーをスローした関数を呼び出した関数にコントロールが戻ります。 このように、onException ブロックで関数が例外をキャッチするか、例外が main 関数に到達するまで、EGL は例外を上方に渡します。 main 関数が例外のキャッチに失敗すると、プログラムは直ちに終了し、その例外のメッセージ・フィールドをログに書き込みます。 リモート側の呼び出し先プログラムで例外が発生すると、呼び出し側プログラムは、オリジナルの例外ではなく、InvocationException を受け取ります。 同様に、サービス関数で例外が発生すると、呼び出し側プログラムには ServiceInvocationException が渡されます。
function FuncOne(myRec serialRecordType)
try
FuncTwo(myRec);
onException(myEx AnyException)
myErrorHandler2(myEx);
end
end
function FuncTwo(myRec serialRecordType)
get next myRec;
end
V6 例外互換モードでは、このように例外が関数から関数に渡されることはありません。これについては、後述します。ハードとソフトの入出力エラー
ファイルの読み取りまたは書き込み時に、EGL はハード とソフト の入出力エラーを区別します。 以下のエラーは、ソフト、つまりデータの損失は生じないと見なされます。
| エラー | 意味 |
|---|---|
| 重複 | 索引付きレコードまたは相対レコードの場合で、このエラーは同じキーを持つ 2 つ目のレコードがあったことを意味します。 |
| endOfFile | シリアル・レコード、索引付きレコード、または相対レコードの場合で、このエラーはファイルの末尾を越えて読み取ろうとしたことを意味します。 |
| noRecordFound | あらゆるレコード・タイプの場合で、このエラーは見つからないレコードを読み取ろうとしたことを意味します。 |
無効なファイル・フォーマットやファイルがいっぱいであるような、その他のエラーはハード・エラーと見なされます。 索引ファイル、相対ファイル、またはシリアル・ファイルに対するハード入出力エラーでは、FileIOException がスローされます。SQL データベースに対するハード入出力エラーでは、SQLException がスローされます。
while(TRUE) // エンドレス・ループ
try
get next mySerialRecord;
if(mySerialRecord is endOfFile)
exit while;
end
onException(myEx AnyException)
myErrorHandler(myEx);
end
end
throwNrfEofExceptions プロパティー
get myCustomer;
if(myCustomer is noRecordFound)
add myCustomer;
end
- ファイル入出力の実行時には、EGL は RuntimeException をスローします。
- SQL 入出力の実行時には、EGL は SQLException をスローします。
- ソフト・エラー後に続行
try get myCustomer; end if (myCustomer is noRecordFound) add myCustomer; end - 例外をキャッチ (推奨手法)
try get myCustomer; onException (myEx FileIOException) if (myCustomer is noRecordFound) add myCustomer; else myErrorHandler(myEx); end end
独自の例外のスロー
nullEx NullValueException{};
...
throw nullEx;
Record CustomerException type Exception
customerNumber INT;
end
...
throw new customerException {
customerNumber = custNum,
message = "Illegal customer number" };
上記のようなカスタム例外レコードには、システム例外レコードと同様に、messageID および message フィールドが自動的に含まれます。V6 例外互換性
以前のバージョンとの互換性のために、EGL のバージョン 6 のエラー処理メソッドを継続して使用できます。
プログラムの v60ExceptionCompatibility プロパティーを YES に設定する際に、プログラムごとに V6 例外モードを指定します。ただし、最適な結果を得るには、すべてのプログラムで同じ設定を使用してください。
try
posNum = abs(myVar);
onException
if(sysVar.errorCode = "00000008") // 無効な入力
myErrorHandler1();
if(sysVar.errorCode = "00000012") // 値を代入できません
myErrorHandler2();
else
myErrorHandler3();
end
- call ステートメントの完了時
- サービスの呼び出し後
- get や replace などのファイル入出力ステートメントの後
- 多数の EGL システム関数の呼び出し後
vgVar.handleSysLibraryErrors = 1;
posNum = abs(myVar);
if(sysVar.errorCode == "00000008") // 無効な入力
myErrorHandler1();
else
if(sysVar.errorCode == "00000012") // 代入できません
myErrorHandler2();
else
exit program (-1);
end
end
ただし、vgVar.handleSysLibraryErrors が 0 (デフォルト) に設定されており、try ブロックを使用した例外のキャッチをしない場合、例外が発生すると、プログラムは強制終了されます。
詳しくは、例外処理を参照してください。