Client LIBMI errors

The DataBlade® API throws the MI_Client_Library_Error event to indicate an error in the client LIBMI library.

The MI_Client_Library_Error event indicates the type of error that has occurred with one of the error levels that the following table shows.
Table 1. Client LIBMI error levels
Error level Description
MI_LIB_BADARG Raised when a DataBlade API function receives an incorrect argument, such as a bad connection descriptor or a NULL value where a pointer is required
MI_LIB_BADSERV Raised when the DataBlade API client library is unable to connect to a database server
MI_LIB_DROPCONN Raised when the DataBlade API client library has lost the connection to the database server
MI_LIB_INTERR Raised when an internal DataBlade API error occurs
MI_LIB_NOIMP Raised when the called function or feature has not yet been implemented
MI_LIB_USAGE Raised when a DataBlade API function is called out of sequence; for example, a call to mi_next_row() occurs when the statement did not return row data

To handle a client LIBMI error:

  1. Write a callback that handles the MI_Client_Library_Error event.
    To handle an MI_Client_Library_Error event, you can write either of the following types of callback function:
    • A client LIBMI callback executes only when the MI_Client_Library_Error event occurs.
    • An all-events callback executes when many events occur and can include handling for the MI_Client_Library_Error event.
  2. Register the callback function that handles the MI_Client_Library_Error event in the client LIBMI application that requires the error handling.

    Use the mi_register_callback() function to register callback functions. After you register a callback that handles the MI_Client_Library_Error event, the client LIBMI invokes this callback instead of performing its default error handling.

Write a callback that handles MI_Client_Library_Error when you need to provide special handling for one or more client LIBMI errors, which Client LIBMI error levels shows. Within the callback, the mi_error_level() function returns the error level for the client LIBMI error. You can also use the following DataBlade API functions to get more details about the client LIBMI error from its error descriptor:
  • The mi_error_sql_state() function returns an SQLSTATE value of "IX000" to indicate a database server-specific error.
  • The mi_error_sqlcode() function returns the database server-specific error.
  • The mi_errmsg() function returns the error message text.
Important: Client LIBMI callbacks are subject to some restrictions on what tasks they can perform.
The following sample code uses special-purpose handlers (not shown) to handle messages (message_handler()) and database server exceptions (exception_handler()). The message_handler() routine might simply display a message on standard error, while the other handlers can take some specific user-defined action based on the type of exception.
/* This routine dispatches callback events for the following
 * events:
 *     MI_Exception (client-side & server-side),
 *     MI_Client_Library_Error (client-side only)
 *     MI_Xact_State_Change (client-side only)
 */
#include "mi.h"
 
MI_CALLBACK_STATUS MI_PROC_CALLBACK
all_callback(event_type, conn, event_data, user_data)
   MI_EVENT_TYPE event_type;
   MI_CONNECTION *conn;
   void *event_data;
   void *user_data;
{
   mi_integer elevel;
   char err_msg[200];
   char *msg;

   switch ( event_type )
      {
      /* A database server exception calls a special-purpose
      ** handler to handle a message (warning) or an
      ** exception. */

      case MI_Exception:
         /* Obtain exception level from event */
         elevel = mi_error_level(event_data);

         switch ( elevel )
            {
            case MI_MESSAGE:
               message_handler(event_data, user_data);
               break;
            case MI_EXCEPTION:
               exception_handler(event_data,
                  user_data);
               break;
            }
         break;

      /* A client LIBMI error is any type of internal
      ** client-library error, library-usage problem, or
      ** a dropped connection. */
      case MI_Client_Library_Error:
         /* Obtain error level from event */
         elevel = mi_error_level(event_data);

         switch ( elevel )
            {
            case MI_LIB_BADARG:
               msg = "MI_LIB_BADARG";
               break;

            case MI_LIB_USAGE:
               msg = "MI_LIB_USAGE";
               break;

            case MI_LIB_INTERR:
               msg = "MI_LIB_INTERR";
               break;

            case MI_LIB_NOIMP:
               msg = "MI_LIB_NOIMP";
               break;

            case MI_LIB_DROPCONN:
               msg = "MI_LIB_DROPCONN";
               break;

            default:
               msg = "UNKNOWN";
               break;
            }
         mi_errmsg(event_data, err_msg, 200);
         fprintf(stderr, "%s: %s\n", msg, err_msg);
         break;

      /* A transaction-state-change event occurs whenever
      ** the client LIBMI module begins or ends a
      ** transaction block. */
      case MI_Xact_State_Change:
         {
         mi_integer  change_type;

         /* Obtain transition type from event */
         change_type = mi_transition_type(event_data);

         switch ( change_type )
            {
            case MI_BEGIN:
               msg = "Transaction started.";
               break;

            case MI_NORMAL_END:
               msg = "Transaction committed.";
               break;

            case MI_ABORT_END:
               msg = "Transaction aborted!";
               break;

            default:
               msg = "Unknown transaction type!";
               break;
            }
         fprintf(stderr, "%s\n", msg);
         break;
         }

      /* No other types of events are expected here,
       * although they can happen. Let the user know
       * what happened and continue.
       */
      default:
         fprintf(stderr, 
            "Caught an unexpected event type.\n");
         break;
      }
   return MI_CB_CONTINUE;
}

The all_callback() callback returns a status of MI_CB_CONTINUE when it is invoked from a C UDR. Therefore, the database server would check for additional callbacks that are registered for the event once it completed execution of all_callback(). If no additional callbacks existed, the database server would abort the UDR.