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.
class SystemException : public
CORBA::Exception {
public:
static const char *_id;
virtual ~SystemException();
CORBA::ULong minor() const;
void minor(CORBA::ULong val);
CORBA::CompletionStatus completed() const;
void completed(CORBA::CompletionStatus status);
...
static SystemException *_downcast(Exception *);
...
};
enum CompletionStatus {
COMPLETED_YES = 0;
COMPLETED_NO = 1;
COMPLETED_MAYBE = 2;
};
You can retrieve and set the minor code using these
SystemException methods. Minor codes are used to provide better information about the type of error.
ULong minor() const;
void
minor(ULong val);
The design of the VisiBroker exception classes allows your program to catch any type of exception and then determine its type by using the _downcast() method. A static method,
_downcast() accepts a pointer to any
Exception object. As with the
_downcast() method defined on
CORBA::Object, if the pointer is of type
SystemException,
_downcast() will return the pointer to you. If the pointer is not of type
SystemException,
_downcast() will return a
NULL pointer.
int main(int argc, char* const* argv) {
try {
// Initialize the ORB.
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Bind to an account.
Account_var account = Account::_bind();
// Get the balance of the account.
CORBA::Float acct_balance = account->balance();
// Print out the balance.
cout << The balance in the account is $
<< acct_balance << endl;
} catch(const CORBA::Exception& e) {
CORBA::SystemException* sys_excep;
sys_excep = CORBA::SystemException::_downcast((CORBA::Exception*)&e);
if(sys_excep != NULL) {
cerr << System Exception occurred: << endl;
cerr << exception name: <<
sys_excep->_name() << endl;
cerr << minor code: << sys_excep->minor() << endl;
cerr << completion code: << sys
_excep->completed() << endl;
} else {
cerr << Not a system exception << endl;
cerr << e << endl;
}
}
}
...
int main(int argc, char* const* argv) {
try {
// Initialize the ORB.
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Bind to an account.
Account_var account = Account::_bind();
// Get account balance.
CORBA::Float acct_balance = account->balance();
// Print out the balance.
cout <<
The balance in the account is $ << acct_balance << endl;
}
// Check for system errors
catch(const CORBA::SystemException& sys_excep) {
cout << System Exception occurred: << endl;
cout << exception name: << sys_excep->_name() << endl;
cout << minor code: << sys_excep->minor() << endl;
cout << completion code: << sys
_excep->completed()
<< endl;
}
}
...
class UserException: public
Exception {
public:
...
static const char *_id;
virtual ~UserException();
static UserException *_downcast(Exception *);
};
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.
The idl2cpp compiler will generate the following code for a
AccountFrozen exception class:
class Account : public virtual CORBA::Object {
...
class
AccountFrozen: public
CORBA_UserException {
public:
static const CORBA_Exception::Description description;
AccountFrozen() {}
static CORBA::Exception *
_factory() {
return new AccountFrozen();
}
~AccountFrozen() {}
virtual const CORBA_Exception::Description&
_desc() const;
static AccountFrozen *
_downcast(CORBA::Exception *exc);
CORBA::Exception *
_deep_copy() const {
return new AccountFrozen(*this);
}
void
_raise() const {
raise *this;
}
...
}
The AccountImpl object must be modified to use the exception by raising the exception under the appropriate error conditions.
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.
...
try {
// Initialize the ORB.
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Bind to an account.
Account_var account = Account::_bind();
// Get the balance of the account.
CORBA::Float acct_balance = account->balance();
}
catch(const Account::AccountFrozen& e) {
cerr << AccountFrozen returned: << endl;
cerr << e << endl;
return(0);
}
// Check for system errors
catch(const CORBA::SystemException& sys_excep) {
}
...
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.