Manages in-line error handling.
%INCLUDE CTPUBLIC;
DCL 01 CONNECTION FIXED BIN(31) INIT(0); 01 RETCODE FIXED BIN(31) INIT(0); 01 COMPILER FIXED BIN(31); 01 OPERATION FIXED BIN(31); 01 MSGTYPE FIXED BIN(31); 01 INDEX FIXED BIN(31) INIT(1); 01 BUFFER type; CALL CTBDIAG (CONNECTION, RETCODE, COMPILER, OPERATION, MSGTYPE, INDEX, BUFFER);
(I) Handle for this connection. This connection handle must already be allocated with CTBCONALLOC.
(O) Variable where the result from an executed function returns. Its value is one of the codes listed under “Returns,” in this section.
This argument is ignored.
(I) Operation to perform. Assign this argument one of the following values:
Value |
Meaning |
---|---|
CS_GET (33) |
Retrieves a specific message. |
CS_CLEAR (35) |
Clears message information for this connection. |
CS_INIT (36) |
Initializes in-line error handling. |
CS_STATUS (37) |
Returns the current number of stored messages. |
CS_MSGLIMIT (38) |
Sets the maximum number of messages to store. |
(I) Type of message or structure on which the operation is to be performed. Assign this argument one of the following symbolic values:
CS_CLIENTMSG_TYPE (4700) |
A CLIENTMSG structure. Indicates Client-Library messages. |
CS_SERVERMSG_TYPE (4701) |
A SERVERMSG structure. Indicates messages sent by the Mainframe ClientConnect or other server. |
CS_ALLMSG_TYPE (4702) |
Operation is performed on both Client-Library and server messages. |
SQLCA_TYPE (4703) |
A SQLCA structure. |
SQLCODE_TYPE (4704) |
A SQLCODE structure. |
(I) Index number of the message being retrieved. Messages are numbered sequentially: the first message has an index of 1, the second an index of 2, and so forth.
If MSGTYP is CS_CLIENTMSG_TYPE, then INDEX refers to Client-Library messages only.
If MSGTYP is CS_SERVERMSG_TYPE, then INDEX refers to server messages only.
If MSGTYP is CS_ALLMSG_TYPE, then INDEX refers to both Client-Library and server messages.
INDEX should be initialized to 1.
(I/O) An integer or a variable (“buffer”) that contains the message. See Table 3-11, to learn the relationship between BUFFER and other arguments.
This argument is typically either CHAR, a SQLCA structure, or a CLIENTMSG or SERVERMSG structure.
It is the responsibility of the programmer to provide
a buffer large enough to hold the largest possible message.
CTBDIAG returns one of the following values:
Value |
Meaning |
---|---|
CS_SUCCEED (-1) |
The routine completed successfully. |
CS_FAIL (-2) |
The routine failed. Common reasons for a CTBDIAG failure include:
|
CS_NOMSG (-207) |
The application attempted to retrieve a message for which the index number is greater than the number of messages in the queue. For example, the application attempted to retrieve message number 3, when only 2 messages are queued. |
The following example uses CTBDIAG to prepare to receive messages. This example is taken from the sample program SYCTSAA4 in Appendix A, “Sample Language Application.”
/*------------------------------------------------------------------*/ /* */ /* Subroutine to process input data */ /* */ /*------------------------------------------------------------------*/ PROCESS_INPUT: PROC ; /*------------------------------------------------------------*/ /* allocate a connection to the server */ /*------------------------------------------------------------*/ CSL_CON_HANDLE = 0 ; CALL CTBCONAL( CSL_CTX_HANDLE, CSL_RC, CSL_CON_HANDLE ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONALLOC failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* alter properties of the connection for user-id */ /*------------------------------------------------------------*/ CALL CTBCONPR( CSL_CON_HANDLE, CSL_RC, CS_SET, CS_USERNAME, PF_USER, PF_USER_SIZE, CS_FALSE, OUTLEN ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONPROPS for user-id failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* alter properties of the connection for password */ /*------------------------------------------------------------*/ CALL CTBCONPR( CSL_CON_HANDLE, CSL_RC, CS_SET, CS_PASSWORD, PF_PWD, PF_PWD_SIZE, CS_FALSE, OUTLEN ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONPROPS for password failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* alter properties of the connection for transaction */ /*------------------------------------------------------------*/ CALL CTBCONPR( CSL_CON_HANDLE, CSL_RC, CS_SET, CS_TRANSACTION_NAME, PF_TRAN, PF_TRANL, CS_FALSE, OUTLEN ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONPROPS for transaction failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* alter properties of the connection for Network driver */ /*------------------------------------------------------------*/ SELECT; WHEN (PF_NETDRV = ' ') NETDRIVER = CS_LU62 ; WHEN (PF_NETDRV = 'LU62' | PF_NETDRV = 'lu62') NETDRIVER = CS_LU62 ; WHEN (PF_NETDRV = 'IBMTCPIP' | PF_NETDRV = 'ibmtcpip') NETDRIVER = CS_TCPIP ; WHEN (PF_NETDRV = 'INTERLIN' | PF_NETDRV = 'interlin') NETDRIVER = CS_INTERLINK ; WHEN (PF_NETDRV = 'CPIC' | PF_NETDRV = 'cpic') NETDRIVER = CS_NCPIC ; OTHERWISE DO; MSGSTR = 'Invalid Network driver entered'; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END; END; CALL CTBCONPR( CSL_CON_HANDLE, CSL_RC, CS_SET, CS_NET_DRIVER, NETDRIVER, CS_UNUSED, CS_FALSE, OUTLEN ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONPROPS for Network driver failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* setup retrieval of All Messages */ /*------------------------------------------------------------*/ CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_INIT, CS_ALLMSG_TYPE, CS_UNUSED, CS_UNUSED ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_INIT failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* set the upper limit of number of messages */ /*------------------------------------------------------------*/ PF_MSGLIMIT = 5 ; CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_MSGLIMIT, CS_ALLMSG_TYPE, CS_UNUSED, PF_MSGLIMIT ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_MSGLIMIT failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* open connection to the server or CICS region */ /*------------------------------------------------------------*/ CALL CTBCONNE( CSL_CON_HANDLE, CSL_RC, PF_SERVER, PF_SERVER_SIZE, CS_FALSE ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBCONNECT failed' ; NO_ERRORS_SW = FALSE ; CALL ERROR_OUT; CALL ALL_DONE ; END ; /*------------------------------------------------------------*/ /* invokes SEND_COMMAND routine */ /*------------------------------------------------------------*/ IF NO_ERRORS_SW THEN CALL SEND_COMMAND ;
The following example uses CTBDIAG to retrieve diagnostic messages. This example is taken from the sample program SYCTSAA4 in Appendix A, “Sample Language Application.”
/*------------------------------------------------------------------*/ /* */ /* Subroutine to retrieve any diagnostic messages */ /* */ /*------------------------------------------------------------------*/ GET_DIAG_MESSAGES: PROC ; DCL CNT FIXED BIN(15) ; /*------------------------------------------------------------------*/ /* Disable calls to this subroutine */ /*------------------------------------------------------------------*/ DIAG_MSGS_INITIALIZED = FALSE ; /*------------------------------------------------------------------*/ /* First, get client messages */ /*------------------------------------------------------------------*/ CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_STATUS, CS_CLIENTMSG_TYPE, CS_UNUSED, DF_NUM_OF_MSGS ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_STATUS CLIENTMSG_TYPE failed'; CALL ERROR_OUT ; CALL ALL_DONE ; END ; ELSE DO ; IF DF_NUM_OF_MSGS > 0 THEN DO ; DO CNT = 1 TO DF_NUM_OF_MSGS ; CALL RETRIEVE_CLIENT_MSGS ; END ; END ; END ; /*------------------------------------------------------------------*/ /* Then, get server messages */ /*------------------------------------------------------------------*/ CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, DF_NUM_OF_MSGS ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_STATUS SERVERMSG_TYPE failed' ; CALL ERROR_OUT ; CALL ALL_DONE ; END ; ELSE DO ; IF DF_NUM_OF_MSGS > 0 THEN DO ; DO CNT = 1 TO DF_NUM_OF_MSGS ; CALL RETRIEVE_SERVER_MSGS ; END ; END ; END ; END GET_DIAG_MESSAGES ; /*------------------------------------------------------------------*/ /* */ /* Subroutine to retrieve diagnostic messages from client */ /* */ /*------------------------------------------------------------------*/ RETRIEVE_CLIENT_MSGS: PROC ; I1 = 1 ; CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_GET, CS_CLIENTMSG_TYPE, DF_MSGNO, CLIENT_MSG ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_GET CS_CLIENTMSG_TYPE FAILED' ; CALL ERROR_OUT ; CALL ALL_DONE ; END ; /*------------------------------------------------------------------*/ /* display message text */ /*------------------------------------------------------------------*/ RSLTNO( I1 ) = 'Client Message:' ; I1 = 3 ; CM_SEVERITY_DATA = CM_SEVERITY ; CM_STATUS_DATA = CM_STATUS ; RSLTNO( I1 ) = CM_SEVERITY_HDR || CM_SEVERITY_DATA || CM_STATUS_HDR || CM_STATUS_DATA ; I1 = I1 + 1 ; CM_OC_MSGNO_DATA = CM_MSGNO ; RSLTNO( I1 ) = CM_OC_MSGNO_HDR || CM_OC_MSGNO_DATA ; I1 = I1 + 1 ; IF CM_MSGNO ^= 0 THEN DO ; CM_OC_MSG_DATA = SUBSTR( CM_TEXT, 1, 66 ) ; RSLTNO( I1 ) = ' OC MsgTx: ' || CM_OC_MSG_DATA ; I1 = I1 + 1 ; IF CM_TEXT_LEN > 66 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_TEXT, 67, 66 ) ; RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; IF CM_TEXT_LEN > 132 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_TEXT, 133, 66 ) ; RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; IF CM_TEXT_LEN > 198 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_TEXT, 199 ) ; RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; END ; END ; END ; END ; ELSE DO ; RSLTNO( I1 ) = ' OC MsgTx: No Message!' ; I1 = I1 + 1 ; END ; CM_OS_MSGNO_DATA = CM_OS_MSGNO ; RSLTNO( I1 ) = ' OS MsgNo: ' || CM_OS_MSGNO_DATA ; I1 = I1 + 1 ; IF CM_OS_MSGNO ^= 0 THEN DO ; CM_OS_MSG_DATA = SUBSTR( CM_OS_MSGTXT, 1, 66 ) ; RSLTNO( I1 ) = ' OS MsgTx: ' || CM_OS_MSG_DATA ; I1 = I1 + 1 ; IF CM_OS_MSGTEXT_LEN > 66 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_OS_MSGTXT, 67, 66 ) ; RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; IF CM_OS_MSGTEXT_LEN > 132 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_OS_MSGTXT,133,66 ); RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; IF CM_OS_MSGTEXT_LEN > 198 THEN DO ; CM_OC_MSG_DATA_X = SUBSTR( CM_OS_MSGTXT,199 ); RSLTNO( I1 ) = BLANK_13 || CM_OC_MSG_DATA_X ; I1 = I1 + 1 ; END ; END ; END ; END ; ELSE DO ; RSLTNO( I1 ) = ' OS MsgTx: No Message!' ; I1 = I1 + 1 ; END ; END RETRIEVE_CLIENT_MSGS ; /*------------------------------------------------------------------*/ /* */ /* Subroutine to retrieve diagnostic messages from server */ /* */ /*------------------------------------------------------------------*/ RETRIEVE_SERVER_MSGS: PROC ; CALL CTBDIAG( CSL_CON_HANDLE, CSL_RC, CS_UNUSED, CS_GET, CS_SERVERMSG_TYPE, DF_MSGNO, SERVER_MSG ) ; IF CSL_RC ^= CS_SUCCEED THEN DO ; MSGSTR = 'CTBDIAG CS_GET CS_SERVERMSG_TYPE failed' ; CALL ERROR_OUT ; CALL ALL_DONE ; END ; /*------------------------------------------------------------------*/ /* display message text */ /*------------------------------------------------------------------*/ SM_MSG_NO_DATA = SM_MSGNO ; SM_SEVERITY_DATA = SM_SEV ; SM_STATE_DATA = SM_STATE ; SM_LINE_NO_DATA = SM_LINE ; SM_STATUS_DATA = SM_STATUS ; IF SM_SVRNAME_LEN > 66 THEN SM_SVRNAME_DATA = SUBSTR( SM_SVRNAME, 1, 63 ) || '...' ; ELSE SM_SVRNAME_DATA = SUBSTR( SM_SVRNAME, 1, 66 ) ; IF SM_PROC_LEN > 66 THEN SM_PROC_ID_DATA = SUBSTR( SM_PROC, 1, 63 ) || '...' ; ELSE SM_PROC_ID_DATA = SUBSTR( SM_PROC, 1, 66 ) ; SM_MSG_DATA = SUBSTR( SM_TEXT, 1, 66 ) ; RSLTNO (1) = 'Server Message:' ; RSLTNO (3) = SM_MSG_NO_HDR || SM_MSG_NO_DATA || SM_SEVERITY_HDR || SM_SEVERITY_DATA || SM_STATE_HDR || SM_STATE_DATA ; RSLTNO (4) = SM_LINE_NO_HDR || SM_LINE_NO_DATA || SM_STATUS_HDR || SM_STATUS_DATA ; RSLTNO (5) = SM_SVRNAME_HDR || SM_SVRNAME_DATA ; RSLTNO (6) = SM_PROC_ID_HDR || SM_PROC_ID_DATA ; RSLTNO (7) = SM_MSG_HDR || SM_MSG_DATA ; IF SM_TEXT_LEN > 66 THEN DO ; SM_MSG_DATA_X = SUBSTR( SM_TEXT, 67, 66 ) ; RSLTNO(8) = BLANK_13 || SM_MSG_DATA_X ; IF SM_TEXT_LEN > 132 THEN DO ; SM_MSG_DATA_X = SUBSTR( SM_TEXT, 133, 66 ) ; RSLTNO(9) = BLANK_13 || SM_MSG_DATA_X ; IF SM_TEXT_LEN > 198 THEN DO ; SM_MSG_DATA_X = SUBSTR( SM_TEXT, 198 ) ; RSLTNO(10) = BLANK_13 || SM_MSG_DATA_X ; END ; END ; END ; END RETRIEVE_SERVER_MSGS ;
CTBDIAG manages in-line message handling for a specific connection. If an application has more than one connection, it must make separate CTBDIAG calls for each connection.
Open ClientConnect applications always use CTBDIAG to handle Client-Library and server messages. Applications built with Open Client can provide alternative message-handling facilities.
An application can perform operations on Client-Library messages, server messages, or both.
For example, an application can clear Client-Library messages without affecting server messages:
CALL CTBDIAG (CONNECTION,RETCODE, CS_UNUSED, CS_CLEAR, CS_CLIENTMSG, CS_UNUSED, MSGBUFFER);
CTBDIAG allows an application to retrieve message information into standard Client-Library structures (CLIENTMSG, SERVERMSG, SQLCA or SQLCODE.
When retrieving messages, CTBDIAG assumes that BUFFER points to a structure of the type indicated by MSGTYPE.
An application that is retrieving messages into a SQLCA or SQLCODE structure must set the Client-Library property CS_EXTRA_INF to CS_TRUE. This is because the SQL structures require information that is not ordinarily returned by the Client-Library error handling mechanism.
Use CTBCONPROPS or CSBCONFIG to set CS_EXTRA_INF.
An application that does not use the SQLCA or SQLCODE structures can also set CS_EXTRA_INF to CS_TRUE. In this case, the extra information is returned as standard Client-Library messages.
For more information about CS_EXTRA_INF, see “Properties” and the reference pages for CTBCONPROPS and CSBCONFIG.
WARNING! If CTBDIAG does not have sufficient internal storage space in which to save a new message, it throws away all unread messages and stops saving messages. The next time it is called with OPERATION as CS_GET, it returns a message to indicate the space problem. After returning this message, CTBDIAG starts saving messages again.
An application must initialize in-line error handling before it can retrieve any errors. To initialize in-line error handling, call CTBDIAG with OPERATION as CS_INIT.
Generally, if a connection uses in-line error handling, the application should call CTBDIAG to initialize in-line error handling for a connection immediately after allocating it with CTBCONALLOC.
To clear message information for a connection, an application calls OPERATION as CS_CLEAR.
To clear Client-Library messages only, set MSGTYPE to CS_CLIENTMSG_TYPE.
To clear server messages only, set MSGTYPE to CS_SERVERMSG_TYPE.
To clear both Client-Library and server messages, set MSGTYPE to SQLCA, SQLCODE, or CS_ALLMSG_TYPE.
If OPERATION is CS_CLEAR and MSGTYPE is not CS_ALLMSG_TYPE:
CTBDIAG assumes that BUFFER is a structure of type MSGTYPE.
CTBDIAG clears the buffer by setting it to blanks or zeroes, as appropriate.
Message information is not cleared until an application explicitly calls CTBDIAG with OPERATION as CS_CLEAR. Retrieving a message does not remove it from the message queue.
To retrieve message information, an application calls CTBDIAG with OPERATION as CS_GET, MSGTYPE as the type of structure in which to retrieve the message, INDEX as the index number of the message of interest, and BUFFER as an integer or a variable, as appropriate.
If MSGTYPE is CS_CLIENTMSG_TYPE, INDEX refers only to Client-Library messages.
If MSGTYPE is CS_SERVERMSG_TYPE, INDEX refers only to server messages.
If MSGTYPE has any other value, INDEX refers to the collective “queue” of both types of messages combined.
CTBDIAG creates a messages queue in the buffer and fills the buffer with message information. It returns messages to the client in the order in which they are received.
If an application attempts to retrieve a message with an index that is higher than the highest valid index, CTBDIAG returns CS_NOMSG to indicate that a message is not available.
The Client-Library default behavior is to save an unlimited number of messages. Applications running on platforms with limited memory may want to limit the number of messages that Client-Library saves. The default for MVS is 25.
An application can limit the number of saved Client-Library messages, the number of saved server messages, and the total number of saved messages.
To limit the number of saved messages, an application calls CTBDIAG with OPERATION as CS_MSGLIMIT and MSGTYPE as CS_CLIENTMSG_TYPE, CS_SERVERMSG_TYPE, or CS_ALLMSG_TYPE:
If MSGTYPE is CS_CLIENTMSG_TYPE, then the number of Client-Library messages is limited.
If MSGTYPE is CS_SERVERMSG_TYPE, then the number of server messages is limited.
If MSGTYPE is CS_ALLMSG_TYPE, then the total number of Client-Library and server messages combined is limited.
When a specific message limit is reached, Client-Library discards any new messages of that type. When a combined message limit is reached, Client-Library discards any new messages.
To find out how many messages were retrieved, an application calls CTBDIAG with OPERATION as CS_STATUS and MSGTYPE as the type of message of interest.
Table 3-11 provides a summary of CTBDIAG arguments.
OPERATION |
CTBDIAG action |
MSGTYPE value |
INDEX value |
BUFFER value |
---|---|---|---|---|
CS_INIT |
Initializes in-line error handling. An application must call CTBDIAG with a CS_INIT operation before it can process error messages in line. |
CS_UNUSED |
CS_UNUSED |
Ignored. |
CS_CLEAR |
Clears message information for this connection. If BUFFER is not zeroes and MSGTYPE is not CS_ALLMSG_ TYPE, CTBDIAG clears the buffer by initializing it with blanks or zeroes. |
One of the legal MSGTYPE values.
|
CS_UNUSED |
A buffer for which the type is defined by MSGTYPE. |
CS_GET |
Retrieves a specific message. |
Any legal MSGTYPE value except CS_ALLMSG_TYPE.
|
The index number of the message to retrieve. |
A buffer for which the type is defined by MSGTYPE. |
CS_MSGLIMIT |
Sets the maximum number of messages to store. |
CS_CLIENTMSG_TYPE to limit Client-Library messages only. CS_SERVERMSG_TYPE to limit server messages only. CS_ALLMSG_TYPE to limit the total number of Client-Library and server messages combined. |
CS_UNUSED |
An integer value. |
CS_STATUS |
Returns the current number of stored messages. |
CS_CLIENTMSG_TYPE to retrieve the number of Client-Library messages. CS_SERVERMSG_TYPE to retrieve the number of server messages. CS_ALLMSG_TYPE to retrieve the total number of Client-Library and server messages combined. |
CS_UNUSED |
An integer variable. |
Related topics: