こんにちは、渡邊です。
GeneXusにはDB関連のエラーを処理するError_Handlerルールが以前からありましたが、アプリケーションの例外を処理するException_HandlerルールがGeneXus 16 Upgrade 7から追加されておりましたので、検証してみました。
環境
今回動作確認した環境は以下の通りです。
- バージョン:GeneXus 18 Upgrade 2
- 言語:.Net
確認方法
以下のWeb Panelとプロシージャを作成しました。
WP_Calc:Web Panel
Rules
Exception_Handler('Exception');
Events
Event 'DoCalc'
&Num = PC_Calc.Udp()
msg(&Num.ToString())
Endevent
Sub 'Exception'
PC_Exception.Call(&GXexceptionType, &GXexceptionDetails, &GXexceptionStack)
EndSub
PC_Calc: プロシージャ
Rules
Parm(out:&Num3);
Source
&Num1 = 1
&Num2 = 0
&Num3 = &Num1 / &Num2 //必ず例外が発生
PC_Exception:プロシージャ
Rules
Parm(in:&GXexceptionType, in:&GXexceptionDetails, in:&GXexceptionStack);
Source
Log.Error(!'例外発生')
Log.Error(!'&GXexceptionType:' + &GXexceptionType)
Log.Error(!'&GXexceptionDetails:' + &GXexceptionDetails)
Log.Error(!'&GXexceptionStack:' + &GXexceptionStack)
WP_CalcというWeb Panelから、0で除算して必ず例外が発生するPC_Calcというプロシージャを呼びだしています。
実行結果
WP_CalcのDoCalcイベント実行時のログファイルです。
2023-06-27 14:07:39,603 [.NET ThreadPool Worker] ERROR GeneXusUserLog - 例外発生
2023-06-27 14:07:39,607 [.NET ThreadPool Worker] ERROR GeneXusUserLog - &GXexceptionType:System.DivideByZeroException
2023-06-27 14:07:39,607 [.NET ThreadPool Worker] ERROR GeneXusUserLog - &GXexceptionDetails:Attempted to divide by zero.
2023-06-27 14:07:39,607 [.NET ThreadPool Worker] ERROR GeneXusUserLog - &GXexceptionStack: at System.Decimal.DecCalc.VarDecDiv(DecCalc& d1, DecCalc& d2)
at System.Decimal.op_Division(Decimal d1, Decimal d2)
at GeneXus.Programs.pc_calc.executePrivate() in C:\KBs\GX18U2WWPSample\NETSQLServer002\web\pc_calc.cs:line 83
at GeneXus.Programs.pc_calc.execute(Int16& aP0_Num3) in C:\KBs\GX18U2WWPSample\NETSQLServer002\web\pc_calc.cs:line 43
at GeneXus.Programs.wp_calc.E110U2() in C:\KBs\GX18U2WWPSample\NETSQLServer002\web\wp_calc.cs:line 599
Exception_Handlerルールが実行され、0の除算で例外が発生したことがログで確認できました。
なお、表示される画面はException_Handlerルールを入れる前と同じ、HTTPステータスコードが500の画面が表示されました。
ポイント
Exception_Handlerルールの利用にあたり、ポイントが3点ほどありました。
ポイント① Exception_Handlerルールを記述するオブジェクト
上記のように実装した通り、Exception_Handlerルールを実際に例外が発生するプロシージャではなくWeb Panelに記述し、実行されていることが確認できました。
Exception_Handlerルールは呼び出し元のオブジェクト側に記述することで、呼び出されたオブジェクトにも自動的に継承されるようです。
そのため呼び出し元のオブジェクトに記述すれば、KB全体のコーディング量が減らせます。
なお、試しにMaster Pageに記述して動作確認してみましたが、残念ながら継承されていませんでした。
ポイント② 例外取得内容
WP_CalcからPC_Exceptionに渡している3つの変数(&GXexceptionType、&GXexceptionDetails、&GXexceptionStack)は、例外発生時に自動的にデータがセットされるようです。
ただし、これらの変数はGeneXusの標準変数ではないようで、変数の追加後にデータタイプをvarcharなどの文字列型に変更しないとビルドエラーが発生しました。
ポイント③ 画面制御
CallメソッドやLink関数を使用して例外発生時にエラー画面や特定のURLに遷移するように実装したところ、画面遷移させることができませんでした。
画面遷移させるにはこれまでと同様に、アプリケーションサーバ側の機能でHTTPステータスからエラーハンドリングする必要がありそうです。
まとめ
例外処理の中で画面遷移できたり、Exception_HandlerルールがMaster Pageで一括で実装できればもっと良かったのですが、例外処理ができるようになったことは大きな前進かと思います。
例外が発生しないように注意して実装するのは勿論ですが、今後は万が一に備えてException_Handlerルールを利用したいと思います。
この記事がお役に立ちましたら幸いです。最後までご覧頂きありがとうございました。