Set and use ERROR, ERROR-STRING, and REJECTED
- Last Updated: February 11, 2026
- 5 minute read
- OpenEdge
- Version 13.0
- Documentation
So far, you have seen how everything works when your updates succeed. Next you will build in a simple example of rejecting a change and having that reflected in the user interface. Let us examine the three attributes, ERROR, REJECTED, and ERROR-STRING, that let you log and check the status of your updates.
SAVE-ROW-CHANGES( )
method. If the before-table is UNDO, ERROR, ERROR-STRING, and REJECTED attributes are
lost when a SAVE-ROW-CHANGES block is undone.If necessary, you can temporarily apply the NO-UNDO attribute to a temp-table and change it back to UNDO after a SAVE-ROW-CHANGES completes.
ERROR is a logical attribute on a Data-Set, ProDataSet
temp-table, and temp-table buffer that indicates whether any errors have occurred in
applying changes back to the database.
The attribute is set by ABL when an error is encountered during FILL or SAVE-ROW-CHANGES.
The FILL error condition sets ERROR to true
for the ProDataSet and temp-table for which the error occurred. SAVE-ROW-CHANGES sets
it to true for the ProDataSet and temp-table as well, but also for
the particular buffer that failed in the save attempt. This might
be because of a unique index violation or other constraint violation
that generates a native AVM error, if a trigger procedure for the
database table returns error, or if the record was changed by another
user.
The ERROR attribute can also be set programmatically to
signal an error condition of any kind. If you set ERROR to
true for a buffer, it is not automatically set to true for the buffer's
temp-table and for the ProDataSet. You can set the attribute at
those levels yourself, if you wish. Setting the attribute at the
level of a temp-table or the entire ProDataSet allows you to tell
immediately whether there is an error anywhere in a set of changes.
You can then check each individual row in the updated temp-table
to locate one or more specific rows that have errors.
ERROR-STRING is a character attribute on each
ProDataSet temp-table and on each temp-table row. This attribute is never set by the AVM
because it is not always clear what error message (among several, for example) to store
into the attribute. Your program can store a value into ERROR-STRING to return a useful message to the caller. Setting ERROR-STRING is independent of setting the ERROR condition.
REJECTED is a logical attribute for the ProDataSet,
temp-table, and temp-table buffer. This is never set by the AVM, but can be set
programmatically to indicate that a change was not saved to the database because of an
error condition. The AVM does not set the attribute because it is not possible for it to
automatically determine the scope of a failed update. This depends on the transaction
scoping of the update process when multiple records are involved. The REJECTED attribute can be used to signal to the caller (and
most specifically to the MERGE-CHANGES method) which
rows were and were not successfully updated, so that the proper adjustments can be made
to the client interface or to other logic.
For example, if your transaction scoping is such that a single
error causes the whole set of changes to be rejected, then either
you or the AVM can set the ERROR status for the
one row that actually failed. Because the entire transaction was
undone, however, you could set the REJECTED attribute
to true for every affected row. In this way, the calling procedure
can tell that all the changes were rejected and reset the origin
ProDataSet and the user interface accordingly. At the same time,
you can identify the single row that actually caused the update
to fail, whose ERROR attribute is true, and flag
that as the row that needs to be corrected. This is why ERROR and REJECTED are
separate attributes.
If you use the MERGE-CHANGES method (or MERGE-ROW-CHANGES),
it checks the REJECTED and ERROR attributes
for each row and does the merge accordingly. For each row marked REJECTED or ERROR, MERGE-CHANGES effectively
does a REJECT-ROW-CHANGES internally to restore
the row in the origin ProDataSet to its original values. You can
take advantage of this default behavior, or you can use the REJECT-CHANGES and REJECT-ROW-CHANGES methods
yourself to get exactly the behavior you require.
In the event of an error, you might not want to use MERGE-CHANGES at
all. For example, say the user updates a whole series of OrderLines and
saves them. One of the OrderLines causes an error,
and the nature of the transaction is that none of the changes are
accepted. If you run MERGE-CHANGES on the change
ProDataSet when you get it back on the client, it will restore the ttOline table and
its browse to the state of the rows before the user made the changes.
This does indeed reflect the state of the database, but it is almost
certainly not the behavior you want. Now the user has to remake
all the changes to all the rows in order to resubmit them for update.
Instead, you might check the ERROR attribute
in your own code and use the REJECT-ROW-CHANGES method to
restore just those rows that generated errors to their original
values, so that just those rows need to be corrected. Or you might
not restore any rows to their original values, but simply display
the errors and let the user correct them and resubmit the changes.
Then you can run MERGE-CHANGES when the updates
succeed. This is why these different methods exist, so that you
can determine the behavior you want and program accordingly. Do
not blindly use the top-level methods like MERGE-CHANGES when
they do not give you the behavior you want.
In principle, when you set any of these attributes at the individual row level, you set them and check them on the before-table buffer. However, to provide maximum flexibility, you can set them on either the before-table or after-table buffer and the effect is the same. If you set one of the attributes on the before-table buffer, you can check its value on the corresponding after-table buffer and vice versa. Remember in particular that for deleted rows, there will only be a before-table row that records the delete, so in general you should do your error setting and error checking on the before-table buffers.
As you learned earlier, there is also a DATA-SOURCE-MODIFIED attribute
that indicates whether there was a conflict between the before-table
values for a row being saved and what is currently in the database,
indicating that the database has been changed by another transaction
since the ProDataSet was filled. If this attribute is set for any
row in a temp-table, it is also set for the temp-table itself, and
for the ProDataSet. If a conflict results in a field value or an
entire row not being saved, then the AVM sets the ERROR attribute.
You can use the DATA-SOURCE-MODIFIED attribute
to identify conflicts and flag them in the user interface, whether
it is to signal why a change was unsuccessful, or to draw the user's
attention to other changes that were either overwritten by the user's
changes or combined with the user's changes, when the changes are
to different fields.
The ERROR, ERROR-STRING, DATA-SOURCE-MODIFIED, and REJECTED attributes
are all cleared for all tables and rows affected by an ACCEPT-CHANGES, REJECT-CHANGES, MERGE-CHANGES,
or FILL method on a table or ProDataSet, or for
an EMPTY-DATASET method on the ProDataSet or EMPTY-TEMP-TABLE method
on a table.