异常处理语句

您可以添加用于处理操作中的异常的语句。

IRL 提供了报告和处理异常的机制。 发生错误时,规则会抛出异常。 这意味着规则的正常流中断,规则引擎尝试查找异常处理程序,即处理特定类型错误的代码块。 异常处理程序通常执行必要的操作以从错误中恢复。

异常设置

在捕获异常之前,代码必须在某个位置抛出一个异常。 任何 Java™ 代码都可能抛出异常。

throw 表达式是其类型可分配给 Java Throwable 类型或子类的任何类型的表达式。 可以在 API 或规则中指定 throw 表达式。 抛出异常时,可以通过 API 或规则 (使用 try-catch-finally 语句或任何 Java 代码) 捕获异常,这将导致 IRL 代码运行。

注:

抛出的异常是 IlrRunTimeExceptionIlrUserRuntimeException 子类型,用于封装 throw 语句抛出的异常。

  • 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) ; 
   }
}

当传递到 method1 的变量不等于 1时, try-catch 语句使用来自 Java 类的方法调用来抛出异常。 以下是 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") ; 
   } 
}

规则引擎作用域内的任何规则或 Java 代码抛出的异常由该特定异常的 try-catch 语句捕获。

以下 CatchCustomer 规则提供了一个 try-catch 语句块示例,该语句块能够捕获 ILOG® 规则语言和/或 Java 代码抛出的异常。 此规则使用 Java Exception 类的两个类 CustomerItem以及两个子类 TooHighExpenseIsNotMember

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 规则中使用的两个 Java 类 IsNotMemberTooHighExpense :

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;
};