SIDL_THROW(EX_VAR,EX_CLS,MSG) SIDL_CHECK(EX_VAR) SIDL_CLEAR(EX_VAR) SIDL_CATCH(EX_VAR,sidl_NAME)
In these macros, EX_VAR is the exception object itself, EX_CLS is the name of the SIDL type we wish the exception to be in a string, MSG is the message we wish to include with the exception and a string, and sidl_NAME is the type of the exception we expect to catch, as a string.
The following SIDL method taken from the Babel regression tests demonstrates how exceptions are handled.
int getFib(in int n, in int max_depth, in int max_value, in int depth) throws NegativeValueException, FibException;
Here is the C binding for this method:
int32_t ExceptionTest_Fib_getFib( ExceptionTest_Fib self, int32_t n, int32_t max_depth, int32_t max_value, int32_t depth, sidl_BaseInterface *_ex);
Here is an example of how to perform exception handling in C using a
package of macros defined in sidl_Exception.h. Note that the
macros assume the exception class that is being thrown and caught inherits
from or implements
sidl.BaseException -- something guaranteed
by Babel.
#include "sidl_Exception.h" /* ...numerous lines deleted... */ int x; sidl_BaseInterface _ex = NULL; x = ExceptionTest_Fib_getFib(f, 10, 1, 100, 0, &_ex); if (SIDL_CATCH(_ex, "ExceptionTest.TooDeepException")) { traceback(_ex); SIDL_CLEAR(_ex); } else if (SIDL_CATCH(_ex, "ExceptionTest.TooBigException")) { traceback(_ex); SIDL_CLEAR(_ex); } else if (_ex == NULL) { return FALSE; } SIDL_CHECK(_ex); return TRUE; EXIT:; traceback(_ex); SIDL_CLEAR(_ex); return FALSE;
You do not have to use the macros provided in sidl_Exception.h if you do no want to. You can check _ex by checking if it is not NULL and then trying to cast it to the various potential exception types.
The following code snippet shows how to throw an exception in C using the macros from sidl_Exception.h. The first argument to SIDL_THROW is the exception output parameter, and the second argument is the type of exception being thrown. The third argument provides a textual description of the exception.
#include "sidl_Exception.h" /* ...numerous lines deleted... */ int32_t impl_ExceptionTest_Fib_getFib( ExceptionTest_Fib self, int32_t n, int32_t max_depth, int32_t max_value, int32_t depth, sidl_BaseInterface* _ex) { /* DO-NOT-DELETE splicer.begin(ExceptionTest.Fib.getFib) */ if (n < 0) { SIDL_THROW(*_ex, ExceptionTest_NegativeValueException, "called with negative n"); } /* ...lines deleted... */ EXIT:; /* SIDL_THROW macro will jump here. */ /* Clean up code should be here. */ return theValue; /* DO-NOT-DELETE splicer.end(ExceptionTest.Fib.getFib) */ }
The code section labeled EXIT is where you should put clean up code. The caller will ignore all the values leaving your C function (i.e., out or inout parameters) because you have thrown an exception, so your code should delete any references you were planning to return to the caller. It's good practice to set all inout and out array, interface or class pointers to NULL. This makes things work out better for clients who forget to check if an exception occurred or willfully choose to ignore it.