Previous | Table of Contents | Next |
19.8.9.1 Overview of Automation Exception Handling
Automation’s notion of exceptions does not resemble true exception handling as defined in C++ and CORBA. Automation methods
are invoked with a call to IDispatch::Invoke or to a vtable method on a Dual Interface. These methods return a 32-bit HRESULT,
as do almost all COM methods. HRESULT values, which have the severity bit (bit 31 being the high bit) set, indicate that an
error occurred during the call, and thus are considered to be error codes. (In Win16, an SCODE was defined as the lower 31
bits of an HRESULT, whereas in Win32 and for our purposes HRESULT and SCODE are identical.) HRESULTs also have a multibit
field called the facility. One of the predefined values for this field is FACILITY_DISPATCH. Visual Basic 4.0 examines the
return HRESULT. If the severity bit is set and the facility field has the value FACILITY_DISPATCH, then Visual Basic executes
a built-in error handling routine, which pops up a message box and describes the error.
Invoke has among its parameters one of type EXCEPINFO*. The caller can choose to pass a pointer to an EXCEPINFO structure
in this parameter or to pass NULL. If a non-NULL pointer is passed, the callee can choose to handle an error condition by
returning the HRESULT DISP_E_EXCEPTION and by filling in the EXCEPINFO structure.
OLE also provides Error Objects, which are task local objects containing similar information to that contained in the EXCEPINFO
structure. Error objects provide a way for Dual Interfaces to set detailed exception information.
Visual Basic allows the programmer to set up error traps, which are automatically fired when an invocation returns an HRESULT
with the severity bit set. If the HRESULT is DISP_E_EXCEPTION, or if a Dual Interface has filled an Error Object, the data
in the EXCEPINFO structure or in the Error Object can be extracted in the error handling routine.
19.8.9.2 CORBA Exceptions
CORBA exceptions provide data not directly supported by the Automation error handling model. Therefore, all methods of Automation
View Interfaces have an additional, optional out parameter of type VARIANT, which is filled in by the View when a CORBA exception
is detected.
Both CORBA System exceptions and User exceptions map to Pseudo-Automation Interfaces called pseudo-exceptions. Pseudo-exceptions
derive from IForeignException, which in turn derives from IForeignComplexType:
//ODL[odl, dual, uuid(...)]interface DIForeignException: DIForeignComplexType{
[propget] HRESULT EX_majorCode([retval,out] long *val);
[propget] HRESULT EX_repositoryID([retval,out] BSTR *val);};
The EX_Id() method will return the name of the exception. For CORBA exceptions, this will be the unscoped name of the exception.
Additional accessors are available on the DIObjectInfo interface for returning the scoped name and repository id for CORBA
exceptions.
Note – Renaming EX_RepositoryId to EX_Id does break backwards compatibility, but should simplify the use of exceptions from
VB.
The UUID for DIForeignException is:
{A8B553C7-3B72-11cf-BBFC-444553540000}
This interface can also be implemented as generic (nondual) Automation Interface, in which case it is named DForeignException
and its UUID is:
{E977F907-3B75-11cf-BBFC-444553540000}
The attribute EX_majorCode defines the broad category of exceptions raised, and has one of the following numeric values:
NO_EXCEPTION = 0SYSTEM_EXCEPTION = 1USER_EXCEPTION = 2
These values may be specified as an enum in the typelibrary information:
typedef enum {NO_EXCEPTION, SYSTEM_EXCEPTION,USER_EXCEPTION } CORBA_ExceptionType;
The attribute EX_repositoryID is a unique string that identifies the exception. It is the exception type’s repository ID from
the CORBA Interface Repository.
19.8.9.3 CORBA User Exceptions
A CORBA user exception is mapped to a properties-only pseudo-exception whose properties correspond one-to-one with the attributes
of the CORBA user exception, and which derives from the methodless interface DICORBAUserException:
//ODL[odl, dual, uuid(...)]interface DICORBAUserException: DIForeignException{}
The UUID for DICORBAUserException is:
{A8B553C8-3B72-11cf-BBFC-444553540000}
This interface can also be implemented as generic (nondual) Automation Interface, in which case it is named DCORBAUserException
and its UUID is:
{E977F908-3B75-11cf-BBFC-444553540000}
Thus, an OMG IDL exception declaration is mapped to an OLE definition as though it were defined as an interface. The declaration
// OMG IDLexception reject{
string reason;};
maps to the following ODL:
//ODL[odl, dual, uuid(6bfaf02d-9f3b-1658-1dfb-7f056665a6bd)]interface DIreject: DICORBAUserException {
[propget] HRESULT reason([retval,out] BSTR reason);}
19.8.9.4 Operations that Raise User Exceptions
If the optional exception parameter is supplied by the caller and a User Exception occurs, the parameter is filled in with
an IDispatch pointer to an exception Pseudo-Automation Interface, and the operation on the Pseudo-Interface returns the HRESULT
S_FALSE. S_FALSE does not have the severity bit set, so that returning it from the operation prevents an active Visual Basic
Error Trap from being fired, allowing the caller to retrieve the exception parameter in the context of the invoked method.
The View fills in the VARIANT by setting its vt field to VT_DISPATCH and setting the pdispval field to point to the pseudo-exception.
If no exception occurs, the optional parameter is filled with an IForeignException pointer on a pseudo-exception object whose
EX_majorCode property is set to NO_EXCEPTION.
If the optional parameter is not supplied and an exception occurs, and
• If the method was called via the vtable portion of a Dual Interface, then the OLE Error Object is filled by the View.
• If the operation was invoked via IDispatch::Invoke, then
• The operation returns DISP_E_EXCEPTION. • If the caller provided an EXCEPINFO, then it is filled by the View.
Note that in order to support Error Objects, Automation Views must implement the standard OLE interface ISupportErrorInfo.
Table 19-3 EXCEPINFO Usage for CORBA User Exceptions
Field | Description | ||||
wCode | Must be zero. | ||||
bstrSource | <interface name>.<operation name> where the interface and operation names are those of the CORBA interface, which this Automation View is representing. | ||||
bstrDescription | CORBA User Exception [<exception repository id>] where the repository id is that of the CORBA user exception. | ||||
bstrHelpFile | Unspecified | ||||
dwHelpContext | Unspecified | ||||
pfnDeferredFillIn | NULL | ||||
scode | DISP_E_EXCEPTION |
Table 19-4 ErrorObject Usage for CORBA User Exceptions
Property | Description | ||||
bstrSource | <interface name>.<operation name> where the interface and operation names are those of the CORBA interface, which this Automation View is representing. | ||||
bstrDescription | CORBA User Exception: [<exception repository id>] where the repository id is that of the CORBA user exception. | ||||
bstrHelpFile | Unspecified | ||||
dwHelpContext | Unspecified | ||||
GUID | The IID of the Automation View Interface. |
19.8.9.5 CORBA System Exceptions
A CORBA System Exception is mapped to the Pseudo-Exception DICORBASystemException, which derives from DIForeignException:
// ODL[odl, dual, uuid(...)]interface DICORBASystemException: DIForeignException{
[propget] HRESULT EX_minorCode([retval,out] long *val);
[propget] HRESULT EX_completionStatus([retval,out] long
*val);
}
The UUID for DICORBASystemException is:
{1E5FFCA0-563B-11cf-B8FD-444553540000}
This interface can also be implemented as generic (nondual) Automation Interface, in which case it is named DCORBASystemException
and its UUID is:
{1E5FFCA1-563B-11cf-B8FD-444553540000}
The attribute EX_minorCode defines the type of system exception raised, while EX_completionStatus has one of the following
numeric values:
COMPLETION_YES = 0COMPLETION_NO = 1COMPLETION_MAYBE =
These values may be specified as an enum in the typelibrary information:
typedef enum {COMPLETION_YES, COMPLETION_NO,COMPLETION_MAYBE } CORBA_CompletionStatus;
19.8.9.6 Operations that raise system exceptions
As is the case for UserExceptions, system exceptions can be returned to the caller using the optional last parameter, which
is present on all mapped methods.
If the optional parameter is supplied and a system exception occurs, the optional parameter is filled in with an IForeignException
pointer to the pseudo-exception, and the automation return value is S_FALSE. If no exception occurs, the optional parameter
is filled with an IForeignException pointer whose EX_majorCode property is set to NO_EXCEPTION.
If the optional parameter is not supplied and a system exception occurs, the exception is looked up in Table 19-5. This table
maps a subset of the CORBA system exceptions to semantically equivalent FACILITY_DISPATCH HRESULT values. If the exception
is on the table, the equivalent HRESULT is returned. If the exception is not on the table, that is, if there is no semantically
equivalent FACILITY_DISPATCH HRESULT, then the exception is mapped to an HRESULT according to Table 19-5 on page 19-35. This
new HRESULT is used as follows.
• If the operation was invoked via IDispatch::Invoke:
• The operation returns DISP_E_EXCEPTION. • If the caller provided an EXCEPINFO, then it is filled with the scode field set to the new HRESULT value.
• If the method was called via the vtable portion of a Dual Interface:
• The OLE Error Object is filled. • The method returns the new HRESULT
Table 19-5 CORBA Exception to COM Error Codes
CORBA Exception |
COM Error Codes |
||||
BAD_OPERATION | DISP_E_MEMBERNOTFOUND | ||||
NO_RESPONSE | DISP_E_PARAMNOTFOUND | ||||
BAD_INV_ORDER | DISP_E_BADINDEX | ||||
INV_IDENT | DISP_E_UNKNOWNNAME | ||||
INV_FLAG | DISP_E_PARAMNOTFOUND | ||||
DATA_CONVERSION | DISP_E_OVERFLOW |
Table 19-6 EXCEPINFO Usage for CORBA System Exceptions Table 19-7 ErrorObject Usage for CORBA System Exceptions
Field | Description | ||||
wCode | Must be zero. | ||||
bstrSource | <interface name>.<operation name> where the interface and operation names are those of the CORBA interface, which this Automation View is representing. | ||||
bstrDescription | CORBA System Exception: [<exception repository id>] minor code [<minor code>][<completion status>] where the <exception repository id> and <minor code> are those of the CORBA system exception. <completion status> is “YES,? “NO,? or “MAYBE? based upon the value of the system exceptions’s CORBA completion status. Spaces and square brackets are literals and must be included in the string. | ||||
bstrHelpFile | Unspecified | ||||
dwHelpContext | Unspecified | ||||
pfnDeferredFillIn | NULL | ||||
scode | Mapped COM error code from Table 18-3 on page 18-12. |
Property Description
bstrSource | <interface name>.<operation name> where the interface and operation names are those of the CORBA interface, which this Automation View is representing. | ||||
bstrDescription | CORBA System Exception: [<exception repository id>] minor code [<minor code>][<completion status>] where the <exception repository id> and <minor code> are those of the CORBA system exception. <completion status> is “YES,? “NO,? or “MAYBE? based upon the value of the system exceptions’s CORBA completion status. Spaces and square brackets are literals and must be included in the string. | ||||
bstrHelpFile | Unspecified | ||||
dwHelpContext | Unspecified | ||||
GUID | The IID of the Automation View Interface. |