Specify the connection

The first argument to the mi_db_error_raise() function is a connection descriptor. This connection descriptor can be either a NULL-valued pointer or a pointer to a valid connection. Which values are valid depend on whether the calling module is a UDR or a client LIBMI application.

In a C UDR, you can specify the connection descriptor to mi_db_error_raise() as either of the following values:
  • A NULL-valued pointer, which raises an exception on the parent connection
  • A pointer to the current connection descriptor, which raises an exception on the current connection

Raise an exception on the parent connection

When you specify a NULL-valued connection descriptor to the mi_db_error_raise() function, this function raises the exception against the parent connection, which is the connection on which the C UDR was invoked. This connection might be a client connection or a UDR-owned connection that was passed to mi_exec(), mi_exec_prepared_statement(), or mi_routine_exec().

If the raised exception has an MI_EXCEPTION exception level, the database server aborts both the UDR and the current SQL expression. For both exception levels (MI_EXCEPTION and MI_MESSAGE), the database server passes the event message to the module on the parent connection and returns control to this module. If the UDR needs control of the exception, it must call mi_db_error_raise() with a pointer to the current connection descriptor.

The following example shows how the MI_EXCEPTION exception level causes the my_function() UDR to end when mi_db_error_raise() specifies a NULL-valued pointer as its connection descriptor:
void MI_PROC_VACALLBACK my_function()
{
   ... Processing ... 
   if ( error condition ) 
      {
      ... do any clean-up here ... 
      ret = mi_db_error_raise ((MI_CONNECTION *)NULL,
         MI_EXCEPTION, "FATAL ERROR in my_function()!");
      }
   ... These lines never get reached ... 
}

Execution returns to the code that called my_function(). If this code has an exception callback, this callback determines how the exception handling continues.

Raise an exception on the current connection

When you specify a valid connection descriptor to the mi_db_error_raise() function, this function raises the exception against the specified connection. The DataBlade® API invokes any callbacks that are registered for the MI_Exception event on this same connection. If a registered callback returns the MI_CB_EXC_HANDLED status, control returns to the UDR.

When the my_function() routine registers a callback, the callback can catch the exception with an MI_EXCEPTION exception level, as the following example shows:
void MI_PROC_VACALLBACK
my_function()
{
   conn = mi_open(NULL, NULL, NULL);
   ...
   cback_hndl = mi_register_callback(conn, MI_Exception,
      excpt_callback, NULL, NULL);
   ... Processing ... 
   if ( error condition ) 
      {
      ... do any clean-up here ... 
      ret = mi_db_error_raise (conn, MI_EXCEPTION, 
         "The excpt_callback() function is invoked from \
          my_function().");
      }
   ... These lines do get reached if excpt_callback() 
      returns MI_CB_EXC_HANDLED... 
}

In a client LIBMI application, you must specify a valid connection descriptor to the mi_db_error_raise() function. For an exception callback to be invoked when the mi_db_error_raise() function raises an exception, specify the same connection descriptor as the one on which the callback was registered.

For example, in the following code fragment, the call to mi_db_error_raise() causes the excpt_callback() function to be invoked when an MI_Exception event occurs:
conn1 = mi_open(argv[1], NULL, NULL);
cback_hndl = mi_register_callback(conn1, MI_Exception,
   clnt_callback, (void *)&error, NULL);
...
mi_db_error_raise(conn1, MI_EXCEPTION, 
   "The clnt_callback() callback is invoked.");

Both mi_register_callback(), which registers the callback for the MI_Exception event, and mi_db_error_raise(), which raises the MI_Exception event, specify conn1 as their connection descriptor.