Traditionally on xBase the Database control management was done in advance, that is to say, you just control that no run-time error would be generated and for that job you used the RLock(), FLock() or NetErr() functions. RLock() and FLock() are functions that permit to perform updates on the DBF table when is opened in shared mode and NetErr() function basically permits to check if a USE or APPEND BLANK operation has been made correctly. Logically with Xailer you can still use this same scheme.
Though, this traditional approach of xBase for managing errors results very limited when you start to use other databases like any SQL database due the fact that then there can be multiples causes that can provoke that a upgrade does not finish correctly, and on that case the SQL server notifies the error when you try to make the upgrade and is impossible to know in advance if the operation will be successfully.
Xailer Datacontrols include a complex mechanism for error management that permits to know all the generated errors. At the TDataSource level includes the methods IsError(), LastError(), DelErrors(), GetErrors() and ShowErrorList():
- IsError() returns true if an error is generated
- LastError() returns the description of the last generated error
- DelErrors() Deletes from the error registry all the generated errors
- GetErrors() returns on a multidimensional array all the generated errors
- ShowErrorList() Shows on a window form all the generated errors
At the TDataSet level includes the following read only properties:
- cLastError, with the last error description
- nLastError, with the last error internal number
And the DelError() method to delete the last error generated. (available from version 1.2b)
To establish the way run-time errors are treated the TDataSource class offers two properties:
The first property lAbortOnErrors permits to force a run-time error every time a database error is produced, being its default value false. The second property lDisplayErrors permits to show on screen all the errors when they are produced, by default its value is true.
Based on Xailer initial configuration of this two properties, the way to perform control management will consist on just consult the methods and properties enumerated above. For example:
oDataSet:Update() IF oDataSet:nLastError != 0 MsgInfo( "Update error, process aborted." ) oDataSet:DelError() ENDIF
Since the property lDisplayErrors is by default true, Xailer will also show a message every time a error is produced, reason why you probably prefer to show a unique message setting this property to false and including on your message the information reported by the properties cLastError and nLastError.
Observe how is necessary to blank the properties cLastError and nLastError with the method DelError() for future updates.
Xailer proposes another technique, in my opinion, more easy to control possible errors, using the property lAbortOnErrors. This property has we have commented provokes a run-time error when a database error is produced and is precisely this mechanism the one we are going to use to control the errors. For that, we need to use the classic TRY..CATCH..END block available in xHarbour to control the error:
TRY oDataSet:Update() CATCH Msginfo( "Update error, process aborted." + CRLF + oDataSet:cLastError ) END
Observe how, in difference from the previous system, there is no need to perform a call to the DelError() method and neither is necessary to implement multiple IF sentences to control if a error has occurred . The benefits of this system are more evident when multiple operations must be done on the same dataset:
TRY oDataSource:BeginTransaction() WITH OBJECT oDataSet DO WHILE !:Eof() :FastEdit() ......................... :FastUpdate() :Skip() ENDDO END WITH oDataSource:CommitTrans() CATCH oDataSource:RollBAckTrans() Msginfo( "Update error, process aborted." + CRLF + oDataSet:cLastError ) END
As you can see the initial configuration of Xailer for Datasource lAbortOnErrors to false and lDisplayErrors to true maybe is not the best for your application, though, we believe is the best for the design state and specially for any users that initiate itself in the use of Xailer.
However, even when the property lDisplayErrors is set to false Xailer will notify the error on the Debugger window. (Only available after version 1.2b)