Istruzioni di gestione eccezioni
IRL fornisce meccanismi per la segnalazione e la gestione delle eccezioni. Quando si verifica un errore, la regola genera un'eccezione. Ciò significa che il normale flusso della regola viene interrotto e il motore delle regole tenta di individuare un gestore eccezioni, ossia un blocco di codice che gestisce un tipo particolare di errore. Il gestore eccezioni generalmente esegue le operazioni necessarie per il ripristino dall'errore.
Impostazione eccezione
Prima di poter rilevare un'eccezione, il codice deve generarne una. Qualsiasi codice Java™ può generare un'eccezione.
Un'espressione throw è qualsiasi tipo di espressione il cui tipo è assegnabile al tipo o alla sottoclasse Java Throwable . Un'espressione throw può essere specificata nell'API o in una regola. Quando viene generata un'eccezione, può essere rilevata dall'API o da una regola - con un'istruzione try-catch-finally o da qualsiasi codice Java - che causa l'esecuzione del codice IRL.
Un'eccezione generata è un IlrUserRuntimeException sottotipo di IlrRunTimeException che incapsula l'eccezione generata dall'istruzione throw .
IlrSystemRuntimeExceptionviene generato quando Decision Server rileva un errore al runtime. Questo tipo di eccezione non può essere ripristinato; viene utilizzato solo per scopi di debug.IlrUserRuntimeException, invece, potrebbe essere utilizzato per reimpostare il contesto e riavviare le regole.
Istruzioni try - catch - finally
Le istruzioni try - catch - finally sono:
L'istruzione
tryidentifica un blocco di istruzioni all'interno del quale potrebbe essere generata un'eccezione.L'istruzione
catchdeve essere associata a un'istruzionetrye identifica un blocco di istruzioni che possono gestire un determinato tipo di eccezione. Le istruzioni vengono eseguite se si verifica un'eccezione di un particolare tipo all'interno del blocco try. Possono essere presenti tutte le istruzioni che seguono un'istruzionetrynecessarie. Ogni istruzione gestisce tutte le eccezioni che sono istanze della classe elencata tra parentesi, di una delle relative sottoclassi o di una classe che implementa l'interfaccia elencata tra parentesi.L'istruzione
finallydeve essere associata a un'istruzionetrye identifica un blocco di istruzioni eseguite indipendentemente dal fatto che si verifichi o meno un errore all'interno del bloccotry. L'istruzionefinallyviene generalmente utilizzata per eseguire il cleanup dopo il codice nell'istruzionetry. Se si verifica un'eccezione nel bloccotrye c'è un bloccocatchassociato per gestire l'eccezione, il controllo si trasferisce prima al bloccocatche poi al bloccofinally.
Ecco la forma generale di queste dichiarazioni:
try {
statements
}
catch (ExceptionType1 name) {
statements
}
catch (ExceptionType2 name) {
statements
}
...
finally {
statements
}IRL consente gestori di eccezioni generali che gestiscono più tipi di eccezioni. Tuttavia, i gestori di eccezioni più specializzati possono stabilire quale tipo di eccezione si è verificata e fornire assistenza per il ripristino di tali errori. I gestori troppo generici possono rendere il codice più soggetto a errori rilevando e gestendo le eccezioni che non sono state anticipate e per cui il gestore non era previsto.
Le istruzioni try riportate di seguito dimostrano come creare un'eccezione e generarla.
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) ;
}
}Le istruzioni try-catch utilizzano una chiamata di metodo da una classe Java per generare un'eccezione quando la variabile passata in method1 non è uguale a 1. Ecco 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") ;
}
}Le eccezioni generate da qualsiasi regola o codice Java all'interno dell'ambito del motore delle regole vengono rilevate dalle istruzioni try-catch per tale eccezione specifica.
La seguente regola CatchCustomer fornisce un esempio di blocco di istruzioni try-catch in grado di catturare le eccezioni lanciate dal linguaggio ILOG® Rule e/o dal codice Java. La regola utilizza due classi, Customer e Iteme due sottoclassi della classe Java Exception , TooHighExpense e 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?");
}
}
}Nell'esempio, un cliente riceve un budget. Al cliente non è consentito acquistare articoli che superano il budget allocato. Se il cliente tenta di acquistare articoli che superano il budget, viene generata un'eccezione TooHighExpense . Inoltre, per acquistare gli articoli il cliente deve essere un membro. Se un non membro tenta di acquistare un articolo, viene generata un'eccezione IsNotMember .
Le due classi Java IsNotMember e TooHighExpense utilizzate nella regola CatchCustomer sono riportate di seguito:
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;
};