By default, the ActiveX proxy raises an ActiveX exception when an EAServer component method raises an exception or an internal error occurs. Visual Basic and most other ActiveX scripting tools do not allow you to handle these errors inline. Instead, control transfers to an error handler (specified by on error goto in Visual Basic) or to a system-wide error dialog box.
Inline exception handling can simplify the code that handles recoverable errors. For example, you can keep program logic that allows a user to retry a failed login in one place, rather than split into mainline code and the separate error handling code. Inline exception handling also allows you to handle errors explicitly in scripting tools that do not allow you to install user-coded error handlers.
The ActiveX proxy supports inline exception handling with Try, Catch, and End methods and an internal exception store. When an exception occurs with inline handling active, the proxy stores the error information rather than raising an ActiveX exception. Each component proxy object supports these methods and contains an exception store that is specific to that object. To handle exceptions inline, call the Try_, Catch_, and End_ methods as follows:
Try_ Activates inline exception handling. Errors or exceptions that occur after calling Try and before End do not raise ActiveX exceptions. Instead, the error is stored in an internal exception store that can be accessed with the Catch method.
Catch_ Check whether an exception of a specified type has occurred. Catch has this syntax:
boolean Catch_( in string exceptionType, out Object exception )
Where exceptionType is the exception type to check for or “...” to check for the occurrence of any exception, and exception is an output variable. If the exception store contains an exception of the specified type, Catch_ copies the exception store to the exception variable, clears the exception store, and returns true.
You can call Catch_ multiple times to check for exceptions of different types.
End_ Deactivates inline exception handling and reverts to the standard ActiveX error handling mechanism. If the exception store contains an exception instance, End_ throws the stored exception as an ActiveX exception.
The Try_ and Catch_ methods do not have the same semantics of structured exception handling in Java or C++. In particular:
Since the exception store holds only one exception instance, you must call Try_ after every proxy method invocation that can raise an exception. Otherwise, an exception in the store can be overwritten by the most recently thrown exception.
If you return from a subroutine with inline exception handling active for an object, it remains active for that object.
Inline exception handling in multithreaded programs requires that you use a separate copy of a proxy object in each thread. See “Using Try_ and Catch_ in multithreaded programs” for more information.
When you call the Catch_ method, you can check for exceptions of a specific type, or for exceptions of any type. To check for any exception, pass “...” as the exception type parameter.
The following example illustrates this style of exception handling:
barcomp.Try_ barcomp.methodThatRaisesException(1007) Dim anyExcep As Object If (barcomp.Catch_("...", anyExcep) = True) Then Dim excepType as String excepType = anyExcep.GetExceptionType if (StrComp(excepType, "Foo/NotValidIdException") == 0) then Dim invalidIdExcep as NotValidIdException set invalidIdExcep = anyExcep Dim id as integer Dim msg as String id = invalidIdExcep.id msg = invalidIdExcep.message Else if (StrComp(excepType, "Foo/NoAuthorizationException") == 0) then Dim noAuthorizationExcep as NoAuthorizationException set noAuthorizationExcep = anyExcep Dim user as String Dim cert as String user = noAuthorizationExcep.username cert = noAuthorizationExcep.certificate Else if (StrComp(excepType, "Jaguar/ClientException") == 0) then Dim systemExcep as SystemException set systemExcep = excep Dim code as integer Dim msg as String code = systemExcep.code msg = systemExcep.message End if Else ' No Exception has occurred. Proceed End If
Exception datatypes are used with the Try_ method when handling exceptions inline. The ActiveX proxy includes predefined system exceptions that correspond to the standard CORBA system exceptions. User-defined exceptions that are declared in an IDL module are also mapped to ActiveX types.
System exceptions In IDL, system exceptions extend the CORBA SystemException IDL type:
interface SystemException { long code; // numeric error code string message; // text error message };
Unlike user-defined exceptions, a component method can throw system exceptions that are not listed in the raises clause of the IDL method signature. The C++ and ActiveX client runtime engines may also raise system exceptions when errors occur in the processing of a method invocation.
In the ActiveX proxy, system exceptions are mapped to the interface SystemException with the following properties and methods:
The Code property specifies the numeric error code.
The Message property specifies the text error description, if available.
The GetExceptionType method returns the string exception identifier (see “Exception identifiers” for more information).
The ActiveX proxy uses SystemException to represent the standard CORBA system exception types that can be returned by components, as well as errors that occur in the ActiveX proxy. “Exception identifiers” lists the system exception types.
User-defined exceptions In IDL, user-defined exceptions are defined using syntax similar to an IDL structure. For example:
exception InvalidValueException { string message; string value; };
User-defined exceptions can be defined within an IDL module or interface. The IDL method signature for a component method must list user-defined exceptions thrown by the method in the raises clause. A method cannot throw user-defined exceptions that are not listed in the raises clause.
In ActiveX, the IDL exception maps to an interface with the following properties and methods:
One get/set property for each member field in the exception, following the datatype mappings for IDL to ActiveX types.
A GetExceptionType method that returns the string exception identifier (see “Exception identifiers” for more information).
Exception identifiers Both system and user-defined exceptions support a GetExceptionType method that returns a string identifier for the exception. The exception identifier for a user-defined exception defined in a module is:
module/exception
Where module is the IDL module name and exception is the IDL exception type. For example, “CtsSecurity/No Certificate Exception”. The exception identifier for an exception defined in an interface is:
module/interface/exception
Where interface is the IDL interface name.
Exception identifiers for system exceptions are predefined, as listed in Table 20-3.
Identifier |
Notes |
---|---|
Jaguar/ClientException |
An error occurred internally to the ActiveX proxy. For example, you may have called a method that uses an unsupported parameter type. |
CORBA/BAD_CONTEXT |
|
CORBA/BAD_INV_ORDER |
|
CORBA/BAD_PARAM |
|
CORBA/BAD_OPERATION |
|
CORBA/BAD_TYPECODE |
|
CORBA/COMM_FAILURE |
A network error occurred. When creating a connection, this usually indicates that the server is down or you have specified the wrong listener address. When calling a method, the error may indicate a transient network fault; you can retry the method. |
CORBA/DATA_CONVERSION |
|
CORBA/FREE_MEM |
|
CORBA/IMP_LIMIT |
|
CORBA/INTERNAL |
|
CORBA/INTF_REPOS |
|
CORBA/INV_FLAG |
|
CORBA/INV_IDENT |
|
CORBA/INV_OBJREF |
|
CORBA/INVALID_TRANSACTION |
|
CORBA/INITIALIZE |
|
CORBA/MARSHAL |
|
CORBA/NO_IMPLEMENT |
The component does not implement the method that you called. |
CORBA/NO_MEMORY |
|
CORBA/NO_RESOURCES |
|
CORBA/NO_RESPONSE |
|
CORBA/NO_PERMISSION |
The user cannot access the server or a specified component. |
CORBA/OBJ_ADAPTER |
|
CORBA/OBJECT_NOT_EXIST |
The object does not exist. This can happen if:
|
CORBA/PERSIST_STORE |
|
CORBA/TRANSACTION_REQUIRED |
The method you attempted to call must be called in the context of an open transaction. |
CORBA/TRANSACTION_ROLLEDBACK |
The method you called rolled back its transaction, or if you have started a client-managed transaction, the transaction timed out. |
CORBA/TRANSIENT |
|
CORBA/UNKNOWN |
This example calls a method CtsSecurity.SSLServiceProvider.setGlobalProperty. This method can be called to specify SSL settings for a connection to a server. For more information, see Chapter 8, “Using SSL in ActiveX Clients,” in the EAServer Security Administration and Programming Guide.
The method signature and the exceptions raised are detailed in the following IDL:
module CtsSecurity { interface SSLServiceProvider { string setGlobalProperty ( in string property, in string value ) raises (CtsSecurity::InvalidPropertyException, CtsSecurity::InvalidValueException); }; exception InvalidPropertyException { string message; string property; }; exception InvalidValueException { string message; string value; }; };
setGlobalProperty raises InvalidValueException if you attempt to set a property to an invalid value, and raises InvalidPropertyException if you specify a property that does not exist.
The following Visual Basic code calls setGlobalProperty and calls the Catch method to handle InvalidValueException inline. Since there is no Catch_ call for InvalidPropertyException, if this exception is thrown, it will be thrown as an ActiveX exception when End_ is called:
Dim ssp as CtsSecurity.SSLServiceProvider // Assume ssp has been properly initialized Dim ivException as CtsSecurity.InvalidValueException // Activate inline exception handling call ssp.Try ssp.setGlobalProperty("qop", "An invalid value") if (ssp.Catch_("CtsSecurity/InvalidValueException", ivException) then call MessageBox ("Invalid value: " & ivException.value & ". " & _ ivException.message, , "Error"); endif call ssp.End_
If your program uses a proxy object in multiple threads and handles exceptions inline, you must call the Duplicate_ method to obtain a copy of the proxy object for use in each thread. Duplicate_ has the following syntax:
Object Duplicate_
Duplicate_ returns a proxy instance of the same type as the original.
Copyright © 2005. Sybase Inc. All rights reserved. |