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