例外処理ステートメント
IRL には、例外を報告および処理するための機能があります。 エラーが生じると、ルールは例外を発します。 これによって、ルールの標準フローが中断され、ルール・エンジンは例外ハンドラー、すなわち、特定の種類のエラーを処理するコードのブロックを見つけようとします。 通常、例外ハンドラーは、エラーから回復するために必要なアクションを実行します。
例外のセットアップ
例外をキャッチするには、どこかのコードが例外をスローする必要があります。 任意の Java™ コードが例外をスローできます。
throw
式は、タイプが Java Throwable
タイプまたはサブクラスに割り当て可能な任意の種類の式です。 throw
式は、API と
ルールのいずれでも指定できます。 例外がスローされた場合、 try
-catch
-finally
ステートメントまたは任意の Java コードを使用して、API またはルールによって例外をキャッチすることができます。これにより、IRL コードが実行されます。
スローされる例外は、throw
ステートメントによってスローされた例外をカプセル化した
IlrRunTimeException
の IlrUserRuntimeException
サブタイプです。
Decision Server が実行時にエラーを検出すると、
IlrSystemRuntimeException
がスローされます。 この種類の例外は回復できません。したがって、デバッグのためだけに使用されます。一方、
IlrUserRuntimeException
を使用すると、コンテキストをリセットしたり、ルールを再起動したりすることができます。
try-catch-finally ステートメント
try-catch-finally ステートメントは、次のように構成されます。
try
ステートメントは、例外がスローされる可能性があるステートメント・ブロックを識別します。catch
ステートメントは、try
ステートメントと関連付ける必要があり、特定タイプの 例外を処理できるステートメント・ブロックを識別します。 このステートメントは、try ブロック内で特定のタイプの例外が発生した場合に実行されます。try
ステートメントのあとには、必要なだけステートメントを 続けることができます。 各ステートメントは、括弧内に記述されたクラス、そのサブクラス、または括弧内に記述されたインターフェースを実装するクラスのインスタンスである例外のいずれか、またはすべてを処理します。finally
ステートメントは、try
ステートメントと関連付ける必要があり、try
ブロック内でエラーが発生するかどうかに関係なく実行されるステートメントのブロックを識別します。 一般に、finally
ステートメントは、try
ステートメントの コード実行後、クリーンアップのために使用されます。try
ブロック内で例外が発生し、例外を処理するための関連catch
ブロックが ある場合、制御はまずcatch
ブロックに移り、その後finally
ブロックに移ります。
次に示すのは、これらのステートメントの一般的な形式です。
try {
statements
}
catch (ExceptionType1 name) {
statements
}
catch (ExceptionType2 name) {
statements
}
...
finally {
statements
}
IRL では、一般例外ハンドラーで、複数の種類の例外を処理することができます。 しかし、より専門化された例外ハンドラーは、発生した例外のタイプを特定することができ、エラーの回復に役立ちます。 ハンドラーが一般的すぎると、予期されずハンドラーが意図されていなかった例外をキャッチおよび処理することで、コードがエラーになりやすい傾向にあります。
以下の try
ステートメントは、例外を作成し、それをスローする方法を示しています。
then {
try {
method1(1) ;
System.out.println("Call method1(1) was OK") ;
}
catch ( Exception e ) {
System.out.println("Catch from method1(1) call") ;
}
try {
method1(2) ;
System.out.println("Call method1(2) was OK") ;
}
catch ( Exception e ) {
System.out.println("Catch from method1(2) call") ;
System.out.println("Exception details :-") ;
System.out.println("Message: " + e) ;
}
}
try
-catch
ステートメントは、Java クラスからのメソッド呼び出しを使用して、 method1 に渡された変数が 1
と等しくない場合に例外をスローします。 以下にメソッド 1 を示します。
public static void method1(i) throws Exception{
if (i == 1) {
System.out.println("method1 - Things are fine \n") ;
}
else {
System.out.println("method1 - Somethings wrong! \n") ;
throw new Exception("method1 - Its an exception! \n") ;
}
}
ルール・エンジンのスコープ内のルールまたは Java コードによってスローされた例外は、その特定の例外の try-catch
ステートメントによってキャッチされます。
以下の CatchCustomer
ルールは、ILOG ルール言語または Java コード (あるいはその両方) によってスローされた例外をキャッチできる try-catch
ステートメント・ブロックの例を示しています。 この規則は、 Customer
と Item
の 2 つのクラスと、Java Exception
クラスの 2 つのサブクラス、 TooHighExpense
と IsNotMember
を使用します。
rule CatchCustomer
{
when {
?c: Customer();
?item: Item();
}
then {
try {
System.out.println("Customer " + ?c.getName() + " wants to buy "
+ " item " + ?item.getLabel() + " for a price of " +
?item.getPrice() + "$");
IsMember(?c);
?c.buy(?item);
}
catch (TooHighExpense ex) {
System.out.println("M/Mrs/Mz " + ?c.getName() + " you have already
bought:");
int j = 0;
for(j = 0; j<?c.getItems().size(); j++) {
java.util.Enumeration ?i = ?c.getItem(j);
System.out.println(" Item: " + ?i.getLabel() + " costs " +
?i.getPrice() + "$");
}
System.out.println("You have at your disposal " + ?c.getBudget() + "$");
System.out.println("The current purchase is not allowed");
}
catch (IsNotMember ex) {
System.out.println("M/Mrs/Mz " + ?c.getName() +
", you are not a member; would you like to
subscribe?");
}
}
}
この例では、顧客に予算が与えられます。 顧客は、割り当てられた予算を超える品物を購入できません。 顧客が予算を超える品物を買おうとすると、TooHighExpense
例外が発生します。 さらに、品物を購入するには、顧客がメンバーでなければなりません。 非メンバーが品物を買おうとすると、IsNotMember
例外が発生します。
CatchCustomer
規則で使用される 2 つの Java クラス IsNotMember
および TooHighExpense
を以下に示します。
public class IsNotMember extends Exception
{
public IsNotMember(String name){
super();
this.customer = name;
}
public void printStackTrace(PrintWriter s){
s.println("An IsNotMember exception has been caused by customer "
+ customer + ". We are sorry but you can not make a purchase "
+ "without being a member.");
super.printStackTrace(s);
}
String customer;
};
public class TooHighExpense extends Exception
{
public TooHighExpense(String name, int expense, int limit, int price){
super();
this.expense = expense;
this.limit = limit;
this.price = price;
this.customer = name;
}
public void printStackTrace(PrintWriter s){
s.println("A TooHighExpense exception has been caused by customer "
+ customer + ". For this customer, the current expense is " + expense +
" and the authorized budget is " + limit +
". The purchase of the item whose price is " + price
+ " is not allowed.");
super.printStackTrace(s);
}
private int price;
private int limit;
private int expense;
String customer;
};