try
and catch
statements, an alternative error mechanism is discussed. This chapter includes the following major sections:Exceptions in the CORBA Model
Exceptions in the CORBA Model
The CORBA specification defines a set of system exceptions that can be raised when errors occur in the processing of a client request. You can define user exceptions in the IDL interface for an objects you create and specify the circumstances under which those exceptions are to be raised. If an object raises an exception while handling a client request, the ORB is responsible for reflecting this information back to the client. The Exception Class
VisiBroker uses C++ classes to represent both system and user exceptions. Since both types of exceptions require similar functionality, SystemException
and UserException
classes are derived from a common Exception
class. When an exception is raised, your application can narrow, or cast down, from the Exception
class to a specific UserException
or SystemException
. The following example shows portions of the Exception
class definition.
class Exception{
...
public:
Exception(const Exception &);
~Exception();
Exception &operator=(const Exception &);
...
friend ostream& operator<<(ostream& strm,
const Exception& exc);
const char *_name() const;
const char*_repository_id() const;
};
_name
and _repository_id
methods on an exception to obtain this information.Assume you have a client application that requests a bind for an object whose server is currently not running, causing an exception to be raised. If your application called the
_name
method on the exception object it would return a string containing "CORBA::NO_IMPLEMENT". If your 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 error conditions shown in a later section.
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;
...
};
CompletionStatus
enumerated values are shown below. COMPLETED_MAYBE
is retuned when the status of the operation cannot be determined.
enum CompletionStatus {You can retrieve and set the completion status using theseCOMPLETED_YES = 0;
COMPLETED_NO = 1;
COMPLETED_MAYBE = 2;
};
SystemException
methods.
CompletionStatus completed();
void completed(CompletionStatus status);
SystemException
methods. Minor codes are used to provide better information about the type of error.
ULong minor() const;void minor(ULong val);
_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.
UNKNOWN
Unknown exception.
BAD_PARAM
An invalid parameter was passed.
NO_MEMORY
Dynamic memory allocation failure.
IMP_LIMIT
Implementation limit violated.
COMM_FAILURE
Communication failure.
INV_OBJREF
Invalid object reference specified.
NO_PERMISSION
No permission for attempted operation.
INTERNAL
ORB internal error.
MARSHAL
Error marshalling parameter or result.
INITIALIZE
ORB initialization failure.
NO_IMPLEMENT
Operation implementation not available.
BAD_TYPECODE
Invalid typecode.
BAD_OPERATION
Invalid operation.
NO_RESOURCES
Insufficient resources to process request.
NO_RESPONSE
Response to request not yet available.
PERSIST_STORE
Persistent storage failure.
BAD_INV_ORDER
Routine invocations out of order.
TRANSIENT
Transient failure.
FREE_MEM
Unable to free memory.
INV_INDENT
Invalid identifier syntax.
INV_FLAG
Invalid flag was specified.
INTF_REPOS
Error accessing interface repository.
BAD_CONTEXT
Error processing context object.
OBJ_ADAPTOR
Failure detected by object adaptor.
DATA_CONVERSION
Data conversion error.
OBJECT_NOT_EXIST
Object is not available.
<<
operator.
Note: If the C++ compiler for your platform does not support exceptions, see page 6-13 for a discussion on using CORBA-defined Environments for handling exceptions.
....If you were to execute the client application with these modifications without a server present, the output shown in the following example would explain that the operation did not complete and the reason for the exception.library *library_object;
try {
library_object = library::_bind();
}
// 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
. Figure 6-7shows how you might modify the client application. The following example shows how the output would appear if a system exception occurred.
....The following example shows output from the system exception.library_var *library_object;
try {
library_object = library::_bind();
}
// 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 {
library_object = library::_bind();
}
// Check for errors
catch(const CORBA::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.
class UserException: public Exception{
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.
// IDL specification for book and library objectsThe IDL compiler will generate this C++ code for a CapacityExceeded exception class.struct book {
string author;
string title;
};
interface library {
exception CapacityExceeded {
};
boolean add_book( in book book_info)
raises(CapacityExceeded);
};
class library: public virtual CORBA::ObjectOn platforms that support C++ exceptions, the{
...
class CapacityExceeded: 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
methods 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.
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;
}
...try {
ret = library_object->add_book(book_entry);
}
// Check for System Exceptions
catch(const library::CapacityExceeded& excep) {
cout << "CapacityExceeded returned:" << endl;
cout << excep; << endl;
// Do any necessary clean-up
return(0);
}
...
// IDL specification for book and library objectsstruct book {
string author;
string title;
};
interface library {
exception CapacityExceeded {
long size;
};
boolean add_book( in book book_info)
raises(CapacityExceeded);
};
.
Applications that use these macros can be more easily ported to all supported platforms. There are two sets of compatibility macros; one set for compilers with exception support and one set for compilers without exception support. The defined constant _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 section.The following section shows compatibility macro mapping for compilers that support exceptions. The macro name is given first followed by the macro expansion.
PMCTRY
try
PMCTHROW(type_name)
throw(type)
PMCTHROW_LAST
throw;
PMCCATCH(type_name, variable_name)
catch(const type &var)
PMCAND_CATCH
catch(const type &var)
PMCEND_CATCH
none
PMCTHROW_SPEC(x)
none or throw(x)
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 shown in Figure 6-17, you should not have to explicitly call these methods yourself.
VisiBroker creates a default
Environment
object for each process. If your platform supports threads, an Environment
object is created for each thread.Environment
class' definition.
class Environment{
private:
Exception *_exception;
public:
Environment();
~Environment();
...
Exception *exception() const;
void exception(Exception *exp);
void clear();
...
};
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();
...
}