Using Information in the Status Vector
Whether or not an error occurs during the execution of an API call, InterBase loads the error status vector with status information. Information consists of one or more InterBase error codes, and error information that can be used to build an error message honed to a specific error.
An application can check the status vector after the execution of most API calls to determine their success or failure. If an error condition is reported, applications can:
- Display InterBase error messages using isc_print_status().
- Set a SQLCODE value corresponding to an InterBase error using isc_sqlcode(), and display the SQLCODE and a SQL error message using isc_print_sqlerror().
- Build individual InterBase error messages in a buffer with isc_interprete(). The buffer must be provided by the application. Using a buffer enables an application to perform additional message processing (for example, storing messages in an error log file). This ability is especially useful on windowing systems that do not permit direct screen writes.
- Capture a SQL error message in a buffer with isc_sql_interprete(). The buffer must be provided by the application.
- Parse for and react to specific InterBase error codes in the status vector.
Contents
Checking the Status Vector for Errors
API functions that return information in the status vector are declared in ibase.h as returning an ISC_STATUS pointer. For example, the function prototype for isc_prepare_transaction() is declared as:
- ISC_STATUS ISC_EXPORT isc_prepare_transaction(ISC_STATUS ISC_FAR *,
- isc_tr_handle ISC_FAR *);
To check the status vector for error conditions after the execution of a function, examine the first element of the status vector to see if it is set to 1, and if so, examine the second element to see if it is not 0. A nonzero value in the second element indicates an error condition. The following C code fragment illustrates how to check the status vector for an error condition:
- #include <ibase.h>
- . . .
- ISC_STATUS status_vector[20];
- . . .
- /* Assume an API call returning status information is called here. */
- if (status_vector[0] == 1 && status_vector[1] > 0) {
- /* Handle error condition here. */
- }
If an error condition is detected, you can use API functions in an error-handling routine to display error messages, capture the error messages in a buffer, or parse the status vector for particular error codes. Display or capture of error messages is only one part of an error-handling routine. Usually, these routines also roll back transactions, and sometimes they can retry failed operations.
Displaying InterBase Error Messages
Use isc_print_status() to display InterBase error messages on the screen. This function parses the status vector to build all available error messages, then uses the C printf() function to write the messages to the display. isc_print_status() requires one parameter, a pointer to a status vector containing error information. For example, the following code fragment calls isc_print_status() and rolls back a transaction on error:
- #include <ibase.h>
- . . .
- ISC_STATUS status_vector[20];
- isc_tr_handle trans;
- . . .
- trans = 0L;
- . . .
- /* Assume a transaction, trans, is started here. */
- /* Assume an API call returning status information is called here. */
- if (status_vector[0] == 1 && status_vector[1] > 0) {
- isc_print_status(status_vector);
- isc_rollback_transaction(status_vector, &trans);
- }
Important: On windowing systems that do not permit direct screen writes with printf(), use isc_interprete() to capture error messages to a buffer.
Tip: For applications that use the dynamic SQL (DSQL) API functions, errors should be displayed using SQL conventions. Use isc_sqlcode() and isc_print_sqlerror() instead of isc_print_status().
Capturing InterBase Error Messages
Use isc_interprete() to build an error message from information in the status vector and store it in an application-refined buffer where it can be further manipulated. Capturing messages in a buffer is useful when applications:
- Run under windowing systems that do not permit direct screen writes.
- Require more control over message display than is possible with isc_print_status().
- Store a record of all error messages in a log file.
- Manipulate or format error messages for display or pass them to a windowing system’s display routines.
isc_interprete() retrieves and formats a single error message each time it is called. When an error occurs, the status vector usually contains more than one error message. To retrieve all relevant error messages, you must make repeated calls to isc_interprete().
Given both the location of a buffer, and the address of the status vector, isc_interprete() builds an error message from the information in the status vector, puts the formatted string in the buffer where an application can manipulate it, and advances the status vector pointer to the start of the next cluster of error information. isc_interprete() requires two parameters, the address of an application buffer to hold formatted message output, and a pointer to the status vector array.
Important: Never pass the status vector array directly to isc_interprete(). Each time it is called, isc_interprete() advances the pointer to the status vector to the next element containing new message information. Before calling isc_interprete(), be sure to set the pointer to the starting address of the status vector.
The following code demonstrates an error-handling routine that makes repeated calls to isc_interprete() to retrieve error messages from the status vector in a buffer, one at a time, so they can be written to a log file:
- #include <ibase.h>
- . . .
- ISC_STATUS status_vector[20];
- isc_tr_handle trans;
- long *pvector;
- char msg[512];
- FILE *efile; /* Code fragment assumes pointer to an open file. */
- trans = 0L;
- . . .
- /* Error-handling routine starts here. */
- /* Always set pvector to point to start of status_vector. */
- pvector = status_vector;
- /* Retrieve first message. */
- isc_interprete(msg, &pvector);
- /* Write first message from buffer to log file. */
- fprintf(efile, "%s\n", msg);
- msg[0] = '-'; /* Append leading hyphen to secondary messages. */
- /* Look for more messages and handle in a loop. */
- while(isc_interprete(msg + 1, &pvector)) /* More? */
- fprintf(efile, "%s\n", msg); /* If so, write it to the log. */
- fclose(efile); /* All done, so close the log file. */
- isc_rollback(status_vector, &trans);
- return(1);
- ...
Note: This code fragment assumes that the log file is properly declared and opened elsewhere in the application before control is passed to this error handler.
Tip: For applications that use the dynamic SQL (DSQL) API functions, errors should be buffered using SQL conventions. Use isc_sqlcode() and isc_sql_interprete() instead of isc_interprete().