#検証#実装方法#機能紹介:Exception_Handlerルール

こんにちは、渡邊です。

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ルールを利用したいと思います。

この記事がお役に立ちましたら幸いです。最後までご覧頂きありがとうございました。