VisiBroker for Java Developer’s Guide : Handling exceptions

Handling exceptions
Exceptions in the CORBA model
The exceptions in the CORBA model include both system and user exceptions. The CORBA specification defines a set of system exceptions that can be raised when errors occur in the processing of a client request. Also, system exceptions are raised in the case of communication failures. System exceptions can be raised at any time and they do not need to be declared in the interface.
You can define user exceptions in IDL for objects you create and specify the circumstances under which those exceptions are to be raised. They are included in the method signature. If an object raises an exception while handling a client request, the VisiBroker ORB is responsible for reflecting this information back to the client.
System exceptions
System exceptions are usually raised by the VisiBroker ORB, though it is possible for object implementations to raise them through interceptors discussed in “Using VisiBroker Interceptors”. When the VisiBroker ORB raises a SystemException, one of the CORBA-defined error conditions is displayed as shown below.
For a listing of explanations and possible causes of these exceptions, see “CORBA exceptions”.
Mismatch detected between the TransactionPolicy in the IOR and the current transaction mode (used in conjunction with VisiTransact).
SystemException class
public abstract class org.omg.CORBA.SystemException extends java.lang.RuntimeException {
protected SystemException(java.lang.String reason,
int minor, CompletionStatus completed) { ... }
public String toString() { ... }
public CompletionStatus completed;
public int minor;
}
Obtaining completion status
System exceptions have a completion status that tells you whether or not the operation that raised the exception was completed. The sample below illustrates the CompletionStatus enumerated values for the CompletionStatus. COMPLETED_MAYBE is returned when the status of the operation cannot be determined.
enum CompletionStatus {
COMPLETED_YES = 0;
COMPLETED_NO = 1;
COMPLETED_MAYBE = 2;
};
Catching system exceptions
Your applications should enclose the VisiBroker ORB and remote calls in a try catch block. The code samples below illustrate how the account client program, discussed in “Developing an example application with VisiBroker”, prints an exception.
public class Client {
public static void main(String[] args) {
try {
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
byte[] managerId = "BankManager".getBytes();
Bank.AccountManager manager =
Bank.AccountManagerHelper.bind(orb, "/bank_agent_poa", managerId);
String name = args.length > 0 ? args[0] : "Jack B. Quick";
Bank.Account account = manager.open(name);
float balance = account.balance();
System.out.println("The balance in " + name + "'s account is $" +
balance);
} catch (Exception e) {
System.err.println(e);
}
}
}
If you were to execute the client program with these modifications and without a server present, the following output would indicate that the operation did not complete and the reason for the exception.
prompt>vbj Client
org.omg.CORBA.OBJECT_NOT_EXIST:
Could not locate the following POA:
poa name : /bank_agent_poa
minor code: 0 completed: No
Downcasting exceptions to a system exception
You can modify the account client program to attempt to downcast any exception that is caught to a SystemException. The following code sample shows you how to modify the client program.
public class Client {
public static void main(String[] args) {
try {
// Initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// Bind to an account
Account account = AccountHelper.bind(orb, "/bank_poa",
"BankAccount".getBytes());
// Get the balance of the account
float balance = account.balance();
// Print the account balance
System.out.println("The account balance is $" + balance);
catch(Exception e) {
if (e instanceof org.omg.CORBA.SystemException) {
System.err.println("System Exception occurred:");
} else {
System.err.println("Not a system exception");
}
System.err.println(e);
}
}
}
The following code sample displays the resulting output if a system exception occurs.
System Exception occurred:
in thread "main" org.omg.CORBA.OBJECT_NOT_EXIST minor code: 0 completed: No
Catching specific types of system exceptions
Rather than catching all types of exceptions, you may choose to specifically catch each type of exception that you expect. The following code sample show this technique.
public class Client {
public static void main(String[] args) {
try {
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
byte[] managerId = "BankManager".getBytes();
Bank.AccountManager manager =
Bank.AccountManagerHelper.bind(orb, "/bank_agent_poa", managerId);
String name = args.length > 0 ? args[0] : "Jack B. Quick";
Bank.Account account = manager.open(name);
float balance = account.balance();
System.out.println("The balance in " + name + "'s account is
$" + balance);
} catch(org.omg.CORBA.SystemException e) {
System.err.println("System Exception occurred:");
System.err.println(e);
}
}
}
User exceptions
When you define your object's interface in IDL, you can specify the user exceptions that the object may raise. The following code sample shows the UserException code from which the idl2java compiler will derive the user exceptions you specify for your object.
public abstract class UserException extends java.lang.Exception {
protected UserException();
protected UserException(String reason);
}
Defining user exceptions
Suppose that you want to enhance the account application, introduced in “Developing an example application with VisiBroker”, so that the account object will raise an exception. If the account object has insufficient funds, you want a user exception named AccountFrozen to be raised. The additions required to add the user exception to the IDL specification for the Account interface are shown in bold.
// Bank.idl
module Bank {
interface Account {
exception AccountFrozen {
};
float balance() raises(AccountFrozen);
};
};
The idl2java compiler will generate the following code for an AccountFrozen exception class.
package Bank;
public interface Account extends com.inprise.vbroker.CORBA.Object,
Bank.AccountOperations, org.omg.CORBA.portable.IDLEntity {
}
package Bank;
public interface AccountOperations {
public float balance () throws Bank.AccountPackage.AccountFrozen;
}
package Bank.AccountPackage;
public final class AccountFrozen extends org.omg.CORBA.UserException {
public AccountFrozen () { ... }
public AccountFrozen (java.lang.String _reason) { ... }
public synchronized java.lang.String toString() { ... }
}
Modifying the object to raise the exception
The AccountImpl object must be modified to use the exception by raising the exception under the appropriate error conditions.
public class AccountImpl extends Bank.AccountPOA {
public AccountImpl(float balance) {
_balance = balance;
}
public float balance() throws AccountFrozen {
if (_balance < 50) {
throws AccountFrozen();
} else {
return _balance;
}
private float _balance;
}
Catching user exceptions
When an object implementation raises an exception, the VisiBroker ORB is responsible for reflecting the exception to your client program. Checking for a UserException is similar to checking for a SystemException. To modify the account client program to catch the AccountFrozen exception, make modifications to the code as shown below.
public class Client {
public static void main(String[] args) {
try {
// Initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// Bind to an account
Account account = AccountHelper.bind(orb, "/bank_poa",
"BankAccount".getBytes());
// Get the balance of the account
float balance = account.balance();
// Print the account balance
System.out.println("The account balance is $" + balance);
}
// Check for AccountFrozen exception
catch(Account.AccountFrozen e) {
System.err.println("AccountFrozen returned:");
System.err.println(e);
}
// Check for system errors
catch(org.omg.CORBA.SystemException sys_excep) {
...
}
}
}
Adding fields to user exceptions
You can associate values with user exceptions. The code sample below shows how to modify the IDL interface specification to add a reason code to the AccountFrozen user exception. The object implementation that raises the exception is responsible for setting the reason code. The reason code is printed automatically when the exception is put on the output stream.
// Bank.idl
module Bank {
interface Account {
exception AccountFrozen {
int reason;
};
float balance() raises(AccountFrozen);
};
};