Error handling when data-operations are performed on the server Professional
Generic Error handling
If an error occurs on the Advantage Database Server, error code and descriptive text can be obtained by the Xbase++ application with two methods of the DacSession object. The Xbase++ runtime is no longer able to know all the details about the error, as the error occured on the server and not on the client side. Whenever such an error occured, the session object which is maintaining the connection to the server can be used to query more detailed information.
nErrorCode := oSession:getLastError()
cErrorMsg := oSession:getLastMessage()
Tip:
The function DbSession() can be used to retrieve the session of the current workarea. This session is in most cases the one which is related to a runtime error occured. Therefore this session object can be used to query the server for further error information. More information about DbSession() can be found in the Xbase++ reference documentation.
Rule and data-integration violations
When using field level validation rules or referential integrity error management starts becoming an integral part of the code. All data manipulation operations, such as DbAppend(), DbDeleted() or REPLACE have a good chance to violate any of the rules which are setup on behalf of the database server. Whenever a client application violates a field level validation rule or referential integrity constraint the ADS DatabaseEngines gets an error from the Advantage Database Server and therefore raises a runtime error.
Due to this behaviour it is important and necessary to write all data manipulation code in such a way that the code is embedded into a begin/end sequence context. This way the error from the Server can be caught, and the Xbase++ application can react accordingly. The following code illustrates this pattern.
01:FUNCTION MyUpdate()
02: LOCAL oError
03: LOCAL oSession
04: LOCAL cbOldError
05:
06: // save old error block and have the update operation
07: // embedded into a sequence block to catch the error
08: //
09: cbOldError := ErrorBlock({|e|Break(e)})
10: BEGIN SEQUENCE
11:
12: // perform the record lock, update the fields, however
13: // field AGE has a validation rule AGE>0 which is clearly
14: // violated with our attempt to assign -15 to the AGE field var.
15: //
16: IF(!DbRLock())
17: RETURN("no update possible, record alread locked by other user")
18: ENDIF
19: FIELD->NAME := "Mascot, the bear"
20: FIELD->AGE := -15
21: DbRUnlock()
22:
23: // the recover part is only executed in case one of the previous
24: // operations raise a runtime error. Such a runtime error can be
25: // initiated by the Advantage Server in case a field level validation
26: // rule was violated.
27: //
28: RECOVER USING oE
29: // first restore the original errorblock otherwise following
30: // runtime errors would shutdown the process with an error in
31: // the error-handling message.
32: //
33: ErrorBlock(cbOldError)
34:
35: // retrieve the session object in which context the operation
36: // has been performed. This way we do not have to pass the
37: // session object through all functions performing operations
38: // against the database server
39: //
40: oSession := DbSession()
41
42: // check for error on behalf of the server, if so return the
43: // descriptive error text to the caller
44: //
45: IF(oSession:GetLastErrror!=0)
46: cErrMsg := oSession:GetLastMessage()
47: ENDIF
48:
49: // perform a rollback for all FIELD values to ensure the
50: // original content is available again
51: //
52: DbRRollback()
53:
54: // return descriptive error text to the caller
55: RETURN(cErrMsg)
56: END SEQUENCE
57:
58: // do not forget to restore the errorblock in case of success
59: //
60: ErrorBlock(cbOldError)
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.