In any REXX script, the SYNTAX condition may be raised as a result of either an improperly written REXX script, or because you pass improperly formatted arguments to a function, or even because of some "severe" run-time error such as low memory.

For more information about SYNTAX handling in a GUI script, see GUI errors.


Non-syntax (ODBC driver) errors

With the exception of certain ODBC functions, most ODBC functions will return an empty string if the ODBC operation is successful, or an error message if a problem occurs. So, you can check the return from a ODBC function, and if it's not an empty string, then do some error handling.

By default, you are expected to check the return string from the ODBC function (except as noted in the individual pages under "Functions Reference") and do error handling if necessary. You will also need to take care of presenting a message to the user (if you desire that).

For example, here is error checking for OdbcAllocEnv (note: we assume OPTIONS "C_CALL"):

/* Setup environment. */
err = OdbcAllocEnv()

/* Check if OdbcAllocEnv succeeded. */
IF err == "" THEN DO

   /* Yes, OdbcAllocEnv succeeded. */

END

ELSE
  GuiSay(err)


Adding a heading to the message

If desired, you can tell Reginald to preface the error message with a heading. This heading will tell you which GUI function caused the failure. For example, if GuiGetMsg is called with no windows being open, then the error message will be DLL function "GUIGETMSG" reports "No open windows". This is more informative when you present the error message to the user.

To enable headings, you must set a variable named OdbcHeading once:

/* Add a heading to error messages. */
OdbcHeading = 1
To restore the default of no headings, then DROP OdbcHeading.


SYNTAX

Alternately, you can choose to have Reginald raise the SYNTAX condition when an error occurs with a ODBC function.

If you have not set up your own SYNTAX handler in your script, then your script will immediately abort with a message box automatically displayed by Reginald. The message box will include the error message, the source line upon which the error occurred, the name of the script that caused the error, and a help button to bring up online help for that error.

On the other hand, if you've used CATCH SYNTAX to set up your own SYNTAX handler, then Reginald will automatically jump to that handler. You'll never even return from that call to the ODBC function. Rather, you'll jump out of the function and jump directly to your CATCH SYNTAX instructions. You can use CONDITION('D') to retrieve the error message, CONDITION('E') to fetch the error number (all ODBC functions return an error number of 250), and CONDITION('M') to display a message box to the user containing the error message.

To enable the SYNTAX reporting feature, set OdbcErr to the value 'SYNTAX' before calling any ODBC functions. Here, we enable the 'SYNTAX' option, and we CATCH SYNTAX. You'll note that we no longer have to check the return from OdbcAllocEnv. Why? Because if an error occurs, we will jump directly to the CATCH SYNTAX. So, it's irrelevant what OdbcAllocEnv returns.

/* Enable SYNTAX option and headings. */
OdbcErr = 'SYNTAX'
OdbcHeading = 1

/* A useful option. */
OPTIONS "C_CALL"

DO

   /* Setup environment. */
   OdbcAllocEnv()

   /* OdbcAllocEnv succeeded if we didn't jump to CATCH SYNTAX. */

   CATCH SYNTAX
      /* Display an error message. */
      CONDITION('M')

END

ERROR

Another alternative you have is for Reginald to raise the ERROR condition when an error occurs with a ODBC function.

If you have not set up your own CATCH ERROR handler, then the ODBC function will simply return the error message as it does by default. Your script will not abort. Of course, you should check the return string for an error message in this case.

On the other hand, if you've used CATCH ERROR to set up your own ERROR handler, then Reginald will automatically jump to your CATCH ERROR instructions, just like in our SYNTAX example above.

To enable the ERROR reporting feature, set OdbcErr to the value 'ERROR' before calling any ODBC functions.

/* Raise ERROR whenever a ODBC function has an error. */
OdbcErr = 'ERROR'

FAILURE

Another alternative you have is for Reginald to raise the FAILURE condition when an error occurs with a ODBC function.

If you have not set up your own CATCH FAILURE handler, then the ODBC function will simply return the error message as it does by default. Your script will not abort. Of course, you should check the return string for an error message in this case.

On the other hand, if you've used CATCH FAILURE to set up your own FAILURE handler, then Reginald will automatically jump to your CATCH FAILURE instructions, just like in our SYNTAX example above.

To enable the FAILURE reporting feature, set OdbcErr to the value 'FAILURE' before calling any ODBC functions.

/* Raise FAILURE whenever a ODBC function has an error. */
OdbcErr = 'FAILURE'

USER

Another alternative you have is for Reginald to raise one of the USER conditions when an error occurs with a ODBC function.

If you have not set up your own CATCH USER handler, then the ODBC function will simply return the error message as it does by default. Your script will not abort. Of course, you should check the return string for an error message in this case.

On the other hand, if you've used CATCH USER to set up your own USER handler, then Reginald will automatically jump to your CATCH USER instructions, just like in our SYNTAX example above.

To enable the USER reporting feature, set OdbcErr to the number of the desired USER condition before calling any ODBC functions. Here, we have modified our example to use USER 10 condition:

/* Enable USER 10 option and headings. */
OdbcErr = 10
OdbcHeading = 1

/* A useful option. */
OPTIONS "C_CALL"

DO

   /* Setup environment. */
   OdbcAllocEnv()

   /* OdbcAllocEnv succeeded if we didn't jump to CATCH USER 10. */

   CATCH USER 10
      /* Display an error message. */
      CONDITION('M')

END

Error messages

Many of the error messages returned by the ODBC functions may appear somewhat cryptic, but its format is designed to help you try to determine what component caused the error, as well as why the error was generated. Typically, there first appears a number enclosed between brackets [ and ]. Microsoft documentation refers to this as the pfNative code. Don't ask me why. Some software engineer apparently thought this was a nifty piece of techo-babble for "error number". I suppose it is not called an error number because it may contain letters as well as numeric digits. So it's not really just a number. For example, a pfNative code could be S1010M. Don't ask me why.

Next, the name of the component that encountered the error is shown between brackets. Here are some typical examples:

[Microsoft][ODBC Driver Manager]
This is an error encountered by the ODBC Driver Manager. This may involve basic problems such as low memory conditions, or missing components on your system, or you're trying to connect to a data source that hasn't been setup on your system.
[Microsoft][ODBC Cursor Library]
This is an error encountered by the ODBC Cursor Library. This may involve incorrect syntax in your SQL statements.
[Microsoft][ODBC SQL Server Driver]
If [ODBC SQL Server Driver] appears, with no other names enclosed by brackets following it, then this is an error encountered by the database driver. This may be due to your database engine's driver not implementing functions you need, or bugs in the driver.
[Microsoft][ODBC SQL Server Driver][Net-Libraryname]
This is an error encountered by the Net-Library, where Net-Libraryname is the name of a SQL Server Net-Library. (See "Setup and Connecting" on MSDN for a list of the names). This also includes errors generated from the underlying network protocol because these errors are reported to the driver from the Net-Library. In these errors, the pfNative code contains the actual error returned by the network. The remainder of the message contains two parts: the Net-Library function called, and (within parenthesis afterward) the underlying network API function called.
[Microsoft][ODBC SQL Server Driver][SQL Server]
This is an error encountered by SQL Server. In this case, the pfNative code is the SQL Server error code. For example, when an application attempts to open a named-pipe connection to a server that is currently shut down, the error string returned is:
[Microsoft][ODBC SQL Server Driver][dbnmpntw]ConnectionOpen (CreateFile())
This indicates that the driver called the dbnmpntw ConnectionOpen function and that dbnmpntw in turn called the named-pipe API function CreateFile.


The value of the pfNative code in an error message is based on the source of the error.

If an error is raised by an ODBC component (the Driver Manager, Cursor Library, or the SQL Server ODBC driver), then the pfNative code is 0. If an error is raised by the server, the pfNative code is the SQL Server error code. For more information about SQL Server errors, see chapters 25 and 26 in the Microsoft SQL Server Administrator's Companion.

If an error is raised by the Net-Library, the pfNative code is the error code returned to the Net-Library from the underlying network protocol stack. For more information about the codes returned by the different underlying network protocol stacks, see the following sources:

dbnmpntw, dbnmp3

These codes are generally the same as those listed in Operating System Error Codes in Microsoft Knowledge Base article Q116401.

dbmssocn, dbmssoc3

These codes, returned by the Winsock API, are listed in "Appendix A, Error Codes," of the Windows Sockets Specification 1.1. The Windows Sockets Specification can be found on the MSDN Library compact disc.

dbmsspxn, dbmsspx3

These codes, returned from Novell, are in Novell NetWare Client Protocol Transport API for C under the section for the API function listed in the szErrorMsg. For example, if the pfNative is 253, and szErrorMsg lists SPXListenForSequencedPacket as the function, the reference manual states a 0xFD (253) return from SPX Listen For Sequenced Packet is a Packet Overflow.

dbmsvinn, dbmsvin3

These codes, returned from Banyan Vines, are listed in the Vines Client Developer's Guide.

dbmsrpcn, dbmsrpc3

These codes, returned by the RPC API, are listed in the RPC section of the C include fiel Winerror.h.