Parsing the Status Vector
Contents
InterBase stores error information in the status vector in clusters of two or three longs. The first cluster in the status vector always indicates the primary cause of the error. Subsequent clusters may contain supporting information about the error,for example, strings or numbers for display in an associated error message. The actual number of clusters used to report supporting information varies from error to error.
In many cases, additional errors may be reported in the status vector. Additional errors are reported immediately following the first error and its supporting information, if any. The first cluster for each additional error message identifies the error. Subsequent clusters may contain supporting information about the error.
How the Status Vector is Parsed
The InterBase error-handling routines, isc_print_status() and isc_interprete(), use routines which automatically parse error message information in the status vector without requiring you to know about its structure. If you plan to write your own routines to read and react to the contents of the status vector, you need to know how to interpret it.
The key to parsing the status vector is to decipher the meaning of the first long in each cluster, beginning with the first cluster in the vector.
Meaning of the First Long in a Cluster
The first long in any cluster is a numeric descriptor. By examining the numeric descriptor for any cluster, you can always determine the:
- Total number of longs in the cluster.
- Kind of information reported in the remainder of the cluster.
- Starting location of the next cluster in the status vector.
Table 10.2 Interpretation of the First Long in Status Vector Clusters
Value | Longs in cluster |
Meaning |
---|---|---|
0 | End of error information in the status vector | |
1 | 2 | Second long is an InterBase error code |
2 | 2 | Second long is the address of string used as a replaceable parameter in a generic InterBase error message |
3 | 3 | Second long is the length, in bytes, of a variable-length string provided by the operating system (most often this string is a file name); third long is the address of the string |
4 | 2 | Second long is a number used as a replaceable parameter in a generic InterBase error message |
5 | 2 | Second long is the address of an error message string requiring no further processing before display |
6 | 2 | Second long is a VAX/VMS error code |
7 | 2 | Second long is a UNIX error code |
8 | 2 | Second long is an Apollo Domain error code |
9 | 2 | Second long is an MS-DOS or OS/2 error code |
10 | 2 | Second long is an HP MPE/XL error code |
11 | 2 | Second long is an HP MPE/XL IPC error code |
12 | 2 | Second long is a NeXT/Mach error code |
- Note: As InterBase is adapted to run on other hardware and software platforms, additional numeric descriptors for specific platform and operating system error codes will be added to the end of this list.
By including ibase.h at the start of your source code, you can use a series of #defines to substitute for hard-coded numeric descriptors in the status vector parsing routines you write. The advantages of using these #defines over hardcoding the descriptors are:
- Your code will be easier to read.
- Code maintenance will be easier should the numbering scheme for numeric descriptors change in a future release of InterBase.
The following table lists the #define equivalents of each numeric descriptor:
Table 10.3 #defines for status vector numeric descriptors
Value | #define | Value | #define |
---|---|---|---|
0 | isc_arg_end | 8 | isc_arg_domain |
1 | sc_arg_gds | 9 | isc_arg_dos |
2 | isc_arg_string | 10 | isc_arg_mpexl |
3 | isc_arg_cstring | 11 | isc_arg_mpexl_ipc |
4 | isc_arg_number | 15 | isc_arg_next_mach |
5 | isc_arg_interpreted | 16 | isc_arg_netware |
6 | isc_arg_vms | 17 | isc_arg_win32 |
7 | isc_arg_unix |
For an example of code that uses these defines, see Status Vector Parsing Example.
Meaning of the Second Long in a Cluster
The second long in a cluster is always one of five items:
- An InterBase error code (1st long = 1).
- A string address (1st long = 2 or 5).
- A string length (1st long = 3).
- A numeric value (1st long = 4).
- An operating system error code (1st long > 5).
InterBase Error Codes
InterBase error codes have two uses. First, they are used internally by InterBase functions to build and display descriptive error message strings. For example, isc_interprete() calls another function which uses the InterBase error code to retrieve a base error message from which it builds an error message string you can display or store in a log file.
Secondly, when you write your own error-handling routine, you can examine the status vector directly, trapping for and reacting to specific InterBase error codes.
When the second long of a cluster is an InterBase error code, then subsequent clusters may contain additional parameters for the error message string associated with the error code. For example, a generic InterBase error message may contain a replaceable string parameter for the name of the table where an error occurs, or it may contain a replaceable numeric parameter for the code of the trigger which trapped the error condition.
If you write your own parsing routines, you may need to examine and use these additional clusters of error information.
String Addresses
String addresses point to error message text. When the first long in the cluster is 2 (isc_arg_string), the address pointed to often contains the name of the database, table, or column affected by the error. In these cases, InterBase functions which build error message strings replace a parameter in a generic InterBase error message with the string pointed to by this address. Other times the address points to an error message hard-coded in a database trigger.
When the first long in the cluster is 5 (isc_arg_interpreted), the address points to a text message which requires no further processing before retrieval. Sometimes this message may be hard-coded in InterBase itself, and other times it may be a system-level error message.
In either of these cases, InterBase functions such as isc_print_status() and isc_interprete() can format and display the resulting error message for you.
String Length Indicators
When the first long in a cluster is 3 (isc_arg_cstring), the numeric value in the second long indicates the length, in bytes, of a message string whose address is stored in the third long in the cluster. This string requires translation into a standard, null-terminated C string before display.
Numeric Values
A numeric value has different meanings depending upon the value of the numeric descriptor in the first long of a cluster. If the first long is 4 (isc_arg_number), a numeric value is used by InterBase functions to replace numeric parameters in generic InterBase error messages during message building. For instance, when an integrity error occurs, InterBase stores the code of the trigger which detects the problem as a numeric value in the status vector. When an InterBase function like isc_interprete() builds the error message string for this error, it inserts the numeric value from the status vector into the generic InterBase integrity error message string to make it more specific.
Operating System Error Codes
If the first long in a cluster is greater than 5, the numeric value in the second long is an error code specific to a particular platform or operating system. InterBase functions should not be used to retrieve and display the specific platform or operating system error message. Consult your operating system manual for information on how to handle such errors.
Meaning of the Third Long in a Cluster
If the first long in a cluster is 3 (isc_arg_cstring), the cluster’s total length is three longs. The third long always contains the address of a message string requiring translation into a standard, null-terminated C string before display. Such a string is often a file or path name. InterBase functions like isc_interprete() automatically handle this translation for you.
Status Vector Parsing Example
The following C example illustrates a simple, brute force parsing of the status vector. The code forces an error condition. The error-handling block parses the status vector array cluster by cluster, printing the contents of each cluster and interpreting it for you.
- #include <ibase.h>
- . . .
- ISC_STATUS status_vector[20];
- main() {
- int done, v; /* end of args?, index into vector */
- int c, extra; /* cluster count, 3 long cluster flag */
- static char *meaning[] = {"End of error information",
- "n InterBase error code"," string address"," string length",
- " numeric value"," system code"};
- /* Assume database is connected and transaction started here. */
- if (status_vector[0] == 1 && status_vector[1] > 0)
- error_exit();
- . . .
- void error_exit(void)
- {
- done = v = 0;
- c = 1;
- while (!done) {
- extra = 0;
- printf("Cluster %d:\n", c);
- printf("Status vector %d: %ld: ", v, status_vector[v]);
- if (status_vector[v] != gds_arg_end)
- printf("Next long is a");
- switch (status_vector[v++]) {
- case gds_arg_end:
- printf("%s\n", meaning[0]);
- done = 1;
- break;
- case gds_arg_gds:
- printf("%s\n", meaning[1]);
- break;
- case gds_arg_end:
- case gds_arg_string:
- case gds_arg_interpreted:
- printf("%s\n", meaning[2]);
- break;
- case gds_arg_number:
- printf("%s\n", meaning[4]);
- break;
- case gds_arg_cstring:
- printf("%s\n", meaning[3]);
- extra = 1;
- break;
- default:
- printf("%s\n", meaning[5]);
- break;
- }
- if (!done) {
- printf("Status vector %d: %ld", v, status_vector[v]);
- v++;/* advance vector pointer */
- c++;/* advance cluster count */
- if (extra) {
- printf(": Next long is a %s\n", meaning[2]);
- printf("Status vector: %d: %ld\n\n", v,
- status_vector[v]);
- v++;
- }
- else
- printf("\n\n");
- }
- }
- isc_rollback_transaction(status_vector, &trans);
- isc_detach_database(&db1);
- return(1);
}
Here is a sample of the output from this program:
- Cluster 1:
- Status vector 0: 1: Next long is an InterBase error code
- Status vector 1: 335544342
- Cluster 2:
- Status vector 2: 4: Next long is a numeric value
- Status vector 3: 1
- Cluster 3:
- Status vector 4: 1: Next long is an InterBase error code
- Status vector 5: 335544382
- Cluster 4:
- Status vector 6: 2: Next long is a string address
- Status vector 7: 156740
- Cluster 5:
- Status vector 8: 0: End of error information
This output indicates that two InterBase errors occurred. The first error code is 335544342. The error printing routines, isc_print_status() and isc_interprete(), use the InterBase error code to retrieve a corresponding base error message. The base error message contains placeholders for replaceable parameters. For error code 335544342, the base error message string is:
- "action cancelled by trigger (%ld) to preserve data integrity"
This error message uses a replaceable numeric parameter, %ld.
In this case, the numeric value to use for replacement, 1, is stored in the second long of the second cluster. When the error printing routine inserts the parameter into the message, it displays the message:
- action cancelled by trigger (1) to preserve data integrity
The second error code is 335544382. The base message retrieved for this error code is:
- "%s"
In this case, the entire message to be displayed consists of a replaceable string. The second long of the fourth cluster contains the address of the replacement string, 156740. This is an error message defined in the trigger that caused the error. When the error printing routine inserts the message from the trigger into the base message, it displays the resulting message:
- -Department name is missing.
Note: This sample program is only meant to illustrate the structure of the status vector and its contents. While the error-handling routine in this program might serve as a limited debugging tool for a program under development, it does not provide useful information for end users. Ordinarily, error-handling blocks in applications should interpret errors, display explanatory error messages, and take corrective action, if appropriate.
For example, if the error-handling routine in the sample program had called isc_print_status() to display the error messages associated with these codes, the following messages would have been displayed:
- action cancelled by trigger (1) to preserve data integrity
- -Department name is missing.