Sentencias de manejo de excepciones
IRL proporciona mecanismos para notificar y manejar excepciones. Cuando se produce un error, la regla genera una excepción. Esto significa que el flujo normal de la regla se interrumpe, y el motor de reglas intenta encontrar un manejador de excepciones, es decir, un bloque de código que maneja un tipo determinado de error. El manejador de excepciones generalmente realiza las acciones necesarias para recuperarse del error.
Configuración de excepción
Antes de que pueda capturar una excepción, el código en algún lugar debe lanzar uno. Cualquier código Java™ puede generar una excepción.
Una expresión throw
es cualquier tipo de expresión cuyo tipo es asignable al tipo o subclase Java Throwable
. Se puede especificar una expresión throw
en la API o en una regla. Cuando se genera una excepción, puede ser capturada por la API o una regla-con una sentencia try
-catch
-finally
o por cualquier código Java-lo que hace que se ejecute el código IRL.
Una excepción generada es un IlrUserRuntimeException
subtipo de IlrRunTimeException
que encapsula la excepción generada por la sentencia throw
.
IlrSystemRuntimeException
se emite cuando Decision Server detecta un error en tiempo de ejecución. Este tipo de excepción no se puede recuperar; sólo se utiliza con fines de depuración.IlrUserRuntimeException
, por otro lado, podría utilizarse para restablecer el contexto y volver a iniciar las reglas.
Las sentencias try-catch-finalmente
Las sentencias try-catch-finalmente son:
La sentencia
try
identifica un bloque de sentencias en el que se puede emitir una excepción.La sentencia
catch
debe estar asociada con una sentenciatry
e identifica un bloque de sentencias que puede manejar un tipo concreto de excepción. Las sentencias se ejecutan si se produce una excepción de un tipo determinado dentro del bloque try. Puede haber tantas sentencias después de una sentenciatry
como sea necesario. Cada sentencia maneja todas y cada una de las excepciones que son instancias de la clase listada entre paréntesis, de cualquiera de sus subclases o de una clase que implementa la interfaz listada entre paréntesis.La sentencia
finally
debe estar asociada con una sentenciatry
e identifica un bloque de sentencias que se ejecuta independientemente de si se produce o no un error dentro del bloquetry
. La sentenciafinally
se utiliza generalmente para limpiar después del código en la sentenciatry
. Si se produce una excepción en el bloquetry
y hay un bloquecatch
asociado para manejar la excepción, el control se transfiere primero al bloquecatch
y, a continuación, al bloquefinally
.
Aquí está la forma general de estas declaraciones:
try {
statements
}
catch (ExceptionType1 name) {
statements
}
catch (ExceptionType2 name) {
statements
}
...
finally {
statements
}
IRL permite manejadores de excepciones generales que manejan varios tipos de excepciones. Sin embargo, los manejadores de excepciones más especializados pueden determinar qué tipo de excepción se ha producido y ayudar en la recuperación de estos errores. Los manejadores que son demasiado generales pueden hacer que el código sea más propenso a errores al capturar y manejar excepciones que no estaban previstas y para las que el manejador no estaba previsto.
Las sentencias try
siguientes muestran cómo crear una excepción y emitirla.
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) ;
}
}
Las sentencias try
-catch
utilizan una llamada de método de una clase Java para generar una excepción cuando la variable pasada a method1 no es igual a 1
. A continuación se muestra 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") ;
}
}
Las excepciones generadas por cualquier regla o código Java dentro del ámbito del motor de reglas son capturadas por las sentencias try-catch
para esa excepción específica.
La siguiente regla CatchCustomer
proporciona un ejemplo de un bloque de sentencias try-catch
capaz de capturar excepciones generadas por el lenguaje de reglas ILOG y/o el código Java. La regla utiliza dos clases, Customer
y Item
, y dos subclases de la clase Java Exception
, TooHighExpense
y 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?");
}
}
}
En el ejemplo, a un cliente se le proporciona un presupuesto. El cliente no tiene permiso para comprar artículos que excedan el presupuesto asignado. Si el cliente intenta comprar artículos que exceden el presupuesto, se genera una excepción TooHighExpense
. Además, para comprar artículos el cliente debe ser miembro. Si un no miembro intenta comprar un artículo, se genera una excepción IsNotMember
.
A continuación se muestran las dos clases Java IsNotMember
y TooHighExpense
utilizadas en la regla CatchCustomer
:
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;
};