Progress KB - ERROR-STATUS:ERROR flag re-set by external procedure OUTPUT parameter




Feedback
Did this article resolve your question/issue?

   

Article

ERROR-STATUS:ERROR flag re-set by external procedure OUTPUT parameter

« Go Back

Information

 
TitleERROR-STATUS:ERROR flag re-set by external procedure OUTPUT parameter
URL Name000037277
Article Number000159844
EnvironmentProduct: OpenEdge
Version: 10.2x, 11.x, 12.x
OS: All supported platforms
Question/Problem Description
After a temp table unique index violation, if the error is cleared a parameter passed to an external procedure resets the error flag with the previous index violation error.

Example:
  • The main procedure starts a super procedure
  • Then calls an internal procedure within the super procedure that adds 2 records violating a NO-UNDO temp table's unique index. 
  • The main procedure calls an external procedure file with an OUTPUT parameter, and the external procedure does nothing more than display a message.
Once the temp table index has been violated and control goes back to the main procedure an assignment statement resets the ERROR-STATUS:ERROR flag before calling the external procedure.  

Although clearing the violation error, the error is reset when the external procedure is called, and it seems to relate to the fact that a parameter is being used in the call.  

ABL code to reproduce the problem:
  • At STEP-1 the error status flag is set and the error message is 132
  • The ASSIGN statement then clears the error
  • At STEP-2 both the error status flag and error message are blank. 
  • Then the call of the external procedure (p-clean.p) displays two 132 error messages and the procedure terminates. 
DO /* TRANSACTION*/:
/* run procedure in super procedure,
this violates a NO-UNDO Temp Table's unique index */

    RUN raiseError.
END.
 
MESSAGE "STEP-1 (After raise of error - run of a bug procedure) " SKIP
    "Error Status : " ERROR-STATUS:ERROR SKIP
    "Error Mess : " ERROR-STATUS:GET-MESSAGE(1) SKIP
    "_MSG(1) : " _MSG(1) VIEW-AS ALERT-BOX.
 
ASSIGN mi-tmp = 1 NO-ERROR.
 
MESSAGE "STEP-2 (After clean of error-status) " SKIP
    "Error Status : " ERROR-STATUS:ERROR SKIP
    "Error Mess : " ERROR-STATUS:GET-MESSAGE(1) SKIP
    "_MSG(1) : " _MSG(1) VIEW-AS ALERT-BOX.
 
DEFINE VARIABLE mh-results AS HANDLE  NO-UNDO.
 
RUN p-clean.p (OUTPUT TABLE-HANDLE mh-results).

 
 
Steps to Reproduce
Clarifying Information
The procedure called in the super procedure creates 2 records in a NO-UNDO temp table with the same index values raising error 132, but also suppressing it with NO-ERROR on its ASSIGN statement:
 
DEFINE TEMP-TABLE tt-tmp /* NO-UNDO */
   FIELDS fc-code    AS CHARACTER
   FIELDS fc-value   AS CHARACTER
   INDEX fc-code IS PRIMARY UNIQUE fc-code.

PROCEDURE raiseError:

   EMPTY TEMP-TABLE tt-tmp.

   CREATE tt-tmp.
   ASSIGN
      tt-tmp.fc-code  = "MyCode"
      tt-tmp.fc-value = "MyValue1"
      NO-ERROR.

   CREATE tt-tmp.
   ASSIGN
      tt-tmp.fc-code  = "MyCode"
      tt-tmp.fc-value = "MyValue2"
      NO-ERROR.
END PROCEDURE.
 
Error Message** tt-tmp already exists with “MyCode”. (132)
Defect/Enhancement Number
Cause
This is expected behavior.  The explanation is as follows:
 
1. When the duplicate key error happens, because the temp-table is 'NO-UNDO' there isn't any undo information saved to recover the previous state of the temp table.  Subsequently the buffer remains with the modifications even though the indexing failed, and the temp table is now in an inconsistent state. 

2. When the client goes into a procedure that has any temp-table parameters, regardless of input or output, a small sub-transaction is made around the parameter processing so that before the procedure is actually entered any existing buffer changes are flushed out.  This is what triggers the 132 error to happen again.  The client then tries to do the indexing again and fails again, which repopulates the ERROR-STATUS and the error message. 

As a general rule, if there is any chance that there could be errors when a record is added or modified in a temp-table, the table either must be UNDO or it must be UNDO at the time of that change.
 
Resolution
There are several ways to resolve the issue:

1.  Define the temp table with UNDO.

2.  Temporarily make the temp-table UNDO:
PROCEDURE raiseError: 

EMPTY TEMP-TABLE tt-tmp.  
TEMP-TABLE tt-tmp:UNDO = TRUE.  /* Temporarily make undo-able */ 

DO TRANSACTION:  /* And you need this as well */  

CREATE tt-tmp. 
ASSIGN 
tt-tmp.fc-code  = "MyCode" 
tt-tmp.fc-value = "MyValue1"  NO-ERROR.      

CREATE tt-tmp. 
ASSIGN 
tt-tmp.fc-code  = "MyCode" 
tt-tmp.fc-value = "MyValue2"  NO-ERROR. 
END. 

TEMP-TABLE tt-tmp:UNDO = FALSE.  /* Restore to NO-UNDO */ 
END PROCEDURE.  /* getDataError */

 
Workaround
Notes
Last Modified Date12/12/2019 3:43 PM
Attachment 
Files
Disclaimer The origins of the information on this site may be internal or external to Progress Software Corporation (“Progress”). Progress Software Corporation makes all reasonable efforts to verify this information. However, the information provided is for your information only. Progress Software Corporation makes no explicit or implied claims to the validity of this information.

Any sample code provided on this site is not supported under any Progress support program or service. The sample code is provided on an "AS IS" basis. Progress makes no warranties, express or implied, and disclaims all implied warranties including, without limitation, the implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample code is borne by the user. In no event shall Progress, its employees, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample code, even if Progress has been advised of the possibility of such damages.