|
Exceptions in the CORBA Model
|
|
System Exceptions
|
|
User Exceptions
|
NOTE: If the C++ compiler for your platform does not support exceptions, see Appendix A for a discussion on using CORBA-defined Environments for handling exceptions.
Exception is the base class for both the SystemException and UserException classes. When an exception is raised, an application can narrow, or cast down, from the Exception class to a specific UserException or SystemException. The following code listing shows portions of the Exception class definition.
Portions of the Exception class definition.
classException{
...
public:
Exception(const Exception &);
~Exception();
Exception &operator=(const Exception &);
...
friend ostream& operator<<(ostream& strm, const char *_name() const;
const char*_repository_id() const;
};
_name and _repository_id methods on an exception to obtain this information.
For example, assume that a client application tries to bind to an object whose server is currently not running, causing an exception to be raised. If the application called the _name method on the exception object it would return a string containing "CORBA::NO_IMPLEMENT". If the application called the _repository_id method, it would return a string containing "IDL:obg.omg/CORBA/NO_IMPLEMENT:1.0".
SystemException, it will be one of the CORBA-defined exceptions.
The SystemException class.
class
SystemException: public Exception{
public:
static const char *_id;
virtual ~SystemException();
ULong minor() const;
void minor(ULong val);
CompletionStatus completed() const;
void completed(CompletionStatus status);
...
static SystemException *_narrow(Exception *exc);
private:
ULong _minor;
completion_status _status;
...
}; Completion Status
System exceptions have a completion status that tells you whether or not the operation that raised the exception was completed. The CompletionStatus enumerated values are shown below. COMPLETED_MAYBE is retuned when the status of the operation cannot be determined.
The CompletionStatus values.
enum CompletionStatus {
You can retrieve and set the completion status using these
COMPLETED_YES = 0;
COMPLETED_NO = 1;
COMPLETED_MAYBE = 2;
};SystemException methods.
CompletionStatus completed();
void completed(CompletionStatus status);
Getting and Setting the Minor Code
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);
Casting to a SystemException
ISB for C++ exception classes allow an application to catch any type of exception and then determine its type by using the _narrow method. A static method, -_narrow accepts a pointer to any Exception object. If the pointer is of type SystemException, _narrow will return the pointer to you. If the pointer is not of type SystemException, _narrow will return a NULL pointer.
Handling System Exceptions
Your applications should always check for system exceptions after making ORB-related calls. The following code example illustrates how you might enhance the library client application to print an exception using the << operator.
NOTE: If the C++ compiler for your platform does not support exceptions, see Appendix A for a discussion on using CORBA-defined Environments for handling exceptions.Printing an exception.
....If you executed the client application with these modifications without a server present, the output shown below would explain that the operation did not complete and give the reason for the exception. Output from modified library client application.
library_var library_object;
try {
...
rc = resolveURI(host, port, uri, p);
library_object = library::_narrow(p);
...
}
// Check for errors
catch(const CORBA::Exception& excep) {
cout << "Error binding to library:" << endl;
cout << excep; << endl;return(0);
}
...
Error binding to library:
Exception: CORBA::NO_IMPLEMENT
Minor: 0
Completion Status: NO
SystemException. The following code example shows how you might modify the client application.
Narrowing an exception to a system exception.
...The following listing shows how the output would appear if a system exception occurred. Output from the system exception.
library_var library_object;
try {
...
rc = resolveURI(host, port, uri, p);
library_object = library::_narrow(p);
...
}
// Check for errors
catch(const CORBA::Exception& excep) {
CORBA::SystemException *sys_excep;
sys_excep = CORBA::SystemException::_narrow(&excep);
if (sys_excep != NULL) {
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;
} else {
cout << "Not a system exception" << endl;
}
return(0);
}
...
System Exception occurred:
exception name: CORBA::NO_IMPLEMENT
minor code: 0
completion code: 1
...
library_var library_object;
try {
rc = resolveURI(host, port, uri, p);
library_object = library::_narrow(p);
}
// Check for errors
catch(constCORBA::SystemException& 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;
}
// Try catching other types of exceptions.
...
UserException class that the IDL compiler will use to derive the user exceptions you specify for your object.
The UserException class.
classUserException: publicException{
public:
...
static const char *_id;
virtual ~UserException();
static UserException *_narrow(Exception *exc);
};
CapacityExceeded to be raised. The additions to the IDL specification for the library interface are shown in bold letters.
Defining User Exceptions
// IDL specification for book and library objectsThe IDL compiler will generate this C++ code for a CapacityExceeded exception class. The
struct book {
string author;
string title;
};
interface library {
exception CapacityExceeded {};
boolean add_book(in book book_info)raises (CapacityExceeded);};
CapacityExceeded class generated by the IDL compiler.
classOn platforms that support C++ exceptions, thelibrary: public virtual CORBA::Object
{
...
classCapacityExceeded:public CORBA::UserException
{
public:
CapacityExceeded();
~CapacityExceeded();
static CapacityExceeded *_narrow(CORBA::Exception *exc);
...
};
...
};
library and _sk_library classes generated by the IDL compiler from this specification will incorporate the throw directive into the add_book method's signature.
The new add_book method signature.
virtual CORBA::Boolean add_book(const book& book_info)
throw (library::CapacityExceeded);
Library object must be modified to use the exception by changing the add_book function prototype and throwing the exception under the appropriate error conditions.
Modifying the object implementation to throw an exception.
CORBA::Boolean Library::add_book(const book& book_info)
throw (library::CapacityExceeded){
CORBA::Boolean ret;
if( (ret = bk_list.add_to_list(book_info)) == 0 )
throw library::CapacityExceeded();return ret;
}
UserException.
...try{
ret = library_object->add_book(book_entry);
}
// Check for System Exceptionscatch(const library::CapacityExceeded& excep){
cout << "CapacityExceeded returned:" << endl;
cout << excep; << endl;
// Do any necessary clean-up
return(0);
}
...
CapacityExceeded exception.
// IDL specification for book and library objects
struct book {
string author;
string title;
};
interface library {
exception CapacityExceeded {
long size;
};
boolean add_book( in book book_info) raises (CapacityExceeded);
};
_PMC_NOEXCEPTIONS determines which macro set will be used. If _PMC_NOEXCEPTIONS is not defined, then the compatibility macros will be mapped as shown in the following table.
Table 5.2 Compatibility macro mapping for compilers that support exceptions.
About the Environment Class
The Environment class enables exceptions to be registered in your application's environment. Methods are provided that allow the PMC macros to determine if a system or user exception has occurred and obtain the details of the exception. If you use the PMC macros, you do not have to explicitly call these methods yourself. ISB for C++ creates a default Environment object for each process. If your platform supports threads, an Environment object is created for each thread. The include file env.h contains the Environment class' definition.
The Environment class.
class
Environment{
private:
Exception *_exception;
public:
Environment();
~Environment();
...
Exception *exception() const;
void exception(Exception *exp);
void clear();
...
}; Environment Methods
The PMC macros make use of the Environment class internally. If you do not want to use the PMC macros and do not have exception support, you can use the Environment class.
The exception method is used by PMCTHROW to raise an exception.
void exception(Exception *exp);
This method is used by PMCCATCH to return the exception that has been set for the environment. If no exception has been set, a NULL pointer is returned.
Exception exception(Exception *exp);
The clear method clears any exception that has been raised in the environment. This method is invoked after the exception has been retrieved.
void clear();
The is_nil method determines if the supplied pointer is NULL. If the pointer is NULL, a value other than zero is returned. If the pointer is not NULL, zero is returned. The behavior of the is_nil method is defined in the CORBA specification.
static Boolean is_nil(Environment_ptr env);
You can use the following CORBA class static method to obtain a pointer to the Environment object for the current process or current thread, if threads are supported.
class CORBA {
...
static Environment& current_environment();
...
}
Last Updated: 02/03/98 15:31:59
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use