Exception handling statements
IRL provides mechanisms for reporting and handling exceptions. When an error occurs, the rule throws an exception. This means that the normal flow of the rule is interrupted, and the rule engine attempts to find an exception handler, that is, a block of code that handles a particular type of error. The exception handler generally does the necessary actions to recover from the error.
Exception setup
Before you can catch an exception, code somewhere must throw one. Any Java™ code can throw an exception.
A throw
expression
is any kind of expression whose type is assignable to the Java Throwable
type or subclass.
A throw
expression can be specified either in the
API or in a rule. When an exception is thrown it can be caught by
the API or a rule—with a try
-catch
-finally
statement
or by any Java code—which
causes the IRL code to run.
A thrown exception is
an IlrUserRuntimeException
subtype of IlrRunTimeException
which
encapsulates the exception thrown by the throw
statement.
IlrSystemRuntimeException
is thrown when Decision Server detects an error at runtime. This kind of exception cannot be recovered; it is used only for debugging purposes.IlrUserRuntimeException
, on the other hand, could be used to reset the context and relaunch the rules.
The try-catch-finally statements
The try-catch-finally statements are:
The
try
statement identifies a block of statements within which an exception might be thrown.The
catch
statement must be associated with atry
statement and identifies a block of statements that can handle a particular type of exception. The statements are run if an exception of a particular type occurs within the try block. There can be as many statements following atry
statement as needed. Each statement handles any and all exceptions that are instances of the class listed in parentheses, of any of its subclasses, or of a class that implements the interface listed in parentheses.The
finally
statement must be associated with atry
statement and identifies a block of statements that is run regardless of whether or not an error occurs within thetry
block. Thefinally
statement is generally used to clean up after the code in thetry
statement. If an exception occurs in thetry
block and there is an associatedcatch
block to handle the exception, control transfers first to thecatch
block and then to thefinally
block.
Here is the general form of these statements:
try {
statements
}
catch (ExceptionType1 name) {
statements
}
catch (ExceptionType2 name) {
statements
}
...
finally {
statements
}
IRL allows general exception handlers that handle multiple types of exceptions. However, more specialized exception handlers can determine what type of exception occurred and assist in the recovery of these errors. Handlers that are too general can make code more error prone by catching and handling exceptions that were not anticipated and for which the handler was not intended.
The
following try
statements demonstrate how to create
an exception and throw it.
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) ;
}
}
The try
-catch
statements
use a method call from a Java class
to throw an exception when the variable passed into method1 is not
equal to 1
. Here is method1:
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") ;
}
}
Exceptions thrown by any rule or Java code within the scope of the rule engine
is caught by the try-catch
statements for that
specific exception.
The following CatchCustomer
rule
provides an example of a try-catch
statement block
capable of catching exceptions thrown by the ILOG Rule language and/or Java code. The rule uses two classes, Customer
and Item
,
and two subclasses of the Java Exception
class, TooHighExpense
and 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?");
}
}
}
In the example, a customer is given a budget. The
customer is not allowed to buy items that exceed the allocated
budget. If the customer attempts to buy items that exceed the budget,
a TooHighExpense
exception is thrown. In addition,
to buy items the customer must be a member. If a nonmember attempts
to buy an item, an IsNotMember
exception is thrown.
The
two Java classes IsNotMember
and TooHighExpense
used
in the CatchCustomer
rule are shown here:
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;
};