LoginSignup
1
2

More than 1 year has passed since last update.

[OutSystems]Extensionからthrowする例外

Last updated at Posted at 2021-06-29

C#で書くExtensionで発生した例外は、OutSystemsのLow-Code部分でどう処理されるのかを確認してみます。
Extensionで色々なパターンで例外を発生させてみて、Action Flowでどの様にHandleされるか。

確認環境

Personal Environment(Version 11.12.0 (Build 30002))
Service Studio (Version 11.11.6)
Integration Studio (Version 11.11.5)

サンプルモジュール

ForgeコンポーネントのV1.0.10。
MainFlow > Exception Screen

結論

Extensionで発生した例外はAllExceptionsでハンドルする。
ハンドルした例外のExceptionMessageプロパティには、C#例外オブジェクトのmessageが設定される。
Exceptionが入れ子になっている(InnerExceptionが設定されている)場合でも一番上位の例外のmessageしか取れない。
Service CenterのErrorログでStack欄を見れば、Extension内の例外の発生順序は確認できる。

Extension Actionで直接発生した例外

以下のように、Extension Actionの先頭でいきなり例外をthrowさせた場合。
MyExceptionはテンプレートそのままのシンプルな例外クラス。

public void MssExceptionTest1() {
	if (1 == 1)
		throw new MyException("Actionメソッドから直接例外をthrowする");
}

Action Flowでは、各種の例外に対してHandle Exceptionを置いて、デバッガでどのパスに来るかを確認しました。
image.png

以下の通り、AllExceptionsでHandleされ、Extension内で例外オブジェクトに渡したメッセージが、ExceptionMessageプロパティに届いてます。UserExceptionとかではハンドルできないんですね。Extensionで発生した例外について、Action Flowで利用できるのは、せいぜい「例外が発生した事実」と「例外メッセージ」くらい。
image.png

Error Log (Service Center)に出力された、Source=「Extension metho」のログのStack。

Actionメソッドから直接例外をthrowする
   at OutSystems.NssExceptionExtension.CssExceptionExtension.MssExceptionTest1()
   at ssAssociateReactive.RssExtensionExceptionExtension.MssExceptionTest1(HeContext heContext)

別のクラスで発生した例外

Extension Actionから別のclassのメソッドを呼び出し、そこで例外を発生させた場合。

Extension Actionでは例外処理しない場合

例外を発生させるClass1.method1()を呼び、try-catchによる処理はしない場合。

public void MssExceptionTest2() {
	var obj = new Class1();
	obj.method1(); // throw new MyException("他のclassで例外を発生させる");
}

この場合もAllExceptions。呼び出したclassで設定した例外メッセージが、ExceptionMessageプロパティに。
image.png

Stack。

他のclassで例外を発生させる
   at OutSystems.NssExceptionExtension.Class1.method1()
   at ssAssociateReactive.RssExtensionExceptionExtension.MssExceptionTest2(HeContext heContext)

Extension Actionで例外をリスローした場合

try-catchで例外を発生させる処理を囲み、catchした例外には手を触れずにそのままリスローする場合。

public void MssExceptionTest3() {
	try
	{
		var obj = new Class1();
		obj.method1(); // throw new MyException("他のclassで例外を発生させる");
	}
	catch (Exception)
	{
		throw;
	}

}

ExceptionMessageは例外をcatchしなかった場合と同じ。
image.png

Stackを確認すると、2行目にthrow;を行っているメソッドが追加されています。

他のclassで例外を発生させる
   at OutSystems.NssExceptionExtension.Class1.method1()
   at OutSystems.NssExceptionExtension.CssExceptionExtension.MssExceptionTest3()
   at ssAssociateReactive.RssExtensionExceptionExtension.MssExceptionTest3(HeContext heContext)

Extension Actionでcatchした例外を詰め直す

C#では、try-catchのcatch内で同じ例外をthrowする場合、「throw;」として、「throw ex;」みたいな書き方をしないようにすすめられています。そのおすすめにあえて反した場合どうなるか。catchした例外を別の例外クラスのオブジェクトにくるんで(InnerExceptionとして渡して)throwしています。

public void MssExceptionTest4() {
	try
	{
		var obj = new Class1();
		obj.method1();
	}
	catch (Exception e)
	{
		throw new My2Exception("catchした例外を他の例外にラップしてthrowする", e);
	}
}

ExceptionMessageには、InnerException(上記コードの「e」オブジェクト)の例外メッセージではなく、throwした例外オブジェクト自体の例外メッセージが設定されていますね。InnerExceptionはロジックから触ることができないようです(リフレクションとか使えば別でしょうが)。
image.png

Stackは以下のように2つに別れました。

[1] catchした例外を他の例外にラップしてthrowする
   at OutSystems.NssExceptionExtension.CssExceptionExtension.MssExceptionTest4()
   at ssAssociateReactive.RssExtensionExceptionExtension.MssExceptionTest4(HeContext heContext)

[2] 他のclassで例外を発生させる
   at OutSystems.NssExceptionExtension.Class1.method1()
   at OutSystems.NssExceptionExtension.CssExceptionExtension.MssExceptionTest4()

例外的ケース:DatabaseException

以下のように、C#でDatabaseExceptionをthrowしたら、Action Flowでも同名のDataBaseExceptionでハンドルできました。
これはおそらく、OutSystemsのDatabaseExceptionを.NETにコンパイルするときに、.NETのDatabaseExceptionクラスに解決しているということと思われます。つまり、このようにたまたま対応する例外クラスを見つけられる場合は、その例外クラスをthrowすることでAction Flowの分岐にも使えるかもしれない。ただ、ドキュメントにも特に記載が無いようだし、これをあてにした処理を書くのはおすすめできませんが。

public void MssExceptionTest5() {
	if (1 == 1)
		throw new DataBaseException("DatabaseExceptionを直接throwしてみる");
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2