When you send a change dataset to the server for updating, system-errors could occur in the server. You need a way to locate and analyze system-generated errors when the dataset is returned to the client. The AVM sets the ERROR attribute when it detects an error during the call to SAVE-ROW-CHANGES or during a FILL operation.

When a system-generated error occurs, the ERROR attribute is set at three levels:

  • For the particular temp-table buffer (row) where the error was detected; it is set in the before-table.
  • For the particular temp-table where the error occurred; it is set for the before-table.
  • For the dataset as a whole.

In the client, you write code to check the ERROR attribute at these levels to locate the row where the error occurred. First you check at the dataset level to determine if an error occurred. If an error did occur, then you typically check each before-table to determine which temp-table has an error. Then you iterate through the before-table rows to determine the particular row where the error occurred.

Enable system-generated ERROR setting in the server

If you want to allow the AVM to set the ERROR attribute in the server, use the NO-ERROR syntax when you call the SAVE-ROW-CHANGES or FILL methods. Otherwise if an error occurs, the server-side procedure fails and no ERROR attributes are set.

Detect system-generated errors on the server

The following is an example of what you need to add to your server-side code to handle system-generated errors. Notice NO-ERROR is specified when calling SAVE-ROW-CHANGES(). If an error occurs when applying changes to the database, the AVM automatically sets the ERROR attribute of the before-table buffer row to TRUE. In addition, the ERROR attributes of the before-table and dataset are also set to TRUE.

. . .
hQuery:GET-FIRST.
DO WHILE hBeforeBuffer:AVAILABLE:
  hBeforeBuffer:SAVE-ROW-CHANGES() NO-ERROR.
  IF hBeforeBuffer:ERROR = TRUE THEN 
  DO:
    /* handle the error */
  END.
  hQuery:GET-NEXT().

END.
. . . 

Detect the ERROR in the client

Assume SAVE-ROW-CHANGES is called in the server for rows of the Order before-table and its child OrderLine before-table rows. During the execution of SAVE-ROW-CHANGES, an error occurs and is set on the dataset, the relevant before-table, and the row that generated the error. For example, if the before-table value does not match what is in the database because another client has updated that particular row, SAVE-ROW-CHANGES fails and the ERROR attribute is set.

In the client, you examine the temp-table rows. Follow these steps to write client code to handle these errors in the returned change dataset:

  1. Check if there are any errors in the dataset as a whole. If not, then you are done. It is not necessary to search the temp-tables for errors.
  2. If errors exist, then check each temp-table for errors.
  3. If you find any temp-tables with errors, examine each row to locate individual errors.

Detect errors at different levels of the dataset

To detect whether an error has occurred on the dataset as a whole, check the ERROR attribute on the dataset handle as follows:
IF hChangeDataSet:ERROR THEN DO:  
  /* Perform ERROR handling */ 
END.
To detect whether an error has occurred in the temp-table of a dataset, check the ERROR attribute on the before-table handle as follows:
IF hBeforeBuffer:ERROR THEN DO: 
   /* Perform ERROR handling */ 
END.

To detect whether an error has occurred in an individual row, use the ERROR attribute on the temp-table buffer handle as follows:

IF hBeforeBuffer:ERROR THEN DO:  
  /* Perform ERROR handling */ 
END.

How rows with errors are merged back into the client's working dataset

Recall that in the client, you call MERGE-CHANGES() to merge the change dataset returned from the server to incorporate the changes back into the client’s dataset. If any row has its ERROR attribute set to TRUE, the row is not merged back into the dataset of the client. MERGE-CHANGES behaves as follows for rows that have their ERROR attribute set:
  • If the row was created in the dataset of the client, the row is deleted.
  • If the row was deleted, the row is added back.
  • If the row was modified, the modifications are rolled back.