1. Tech

Your suggestion is on its way!

An email with a link to:

http://delphi.about.com/od/database/l/aa103001a.htm

was emailed to:

Thanks for sharing About.com with others!

Handling database errors
Introducing error handling techniques in Delphi ADO database application development. Find out about global exception handling and dataset specific error events. See how to write an error logging procedure.
 More of this Feature
Printer friendly versionPrinter friendly version
 Join the Discussion
"Post your views and comments to this chapter of the free Delphi database Programming Course"
Discuss!
 Related Resources
• free DB Course.TOC
• more Database articles
• On errors and exceptions

One of the most important elements of database programming is handling database errors. Any robust (database) application must contain error trapping mechanism to prevent an inexperienced (or careless) user to, for example, input a bad value into a data field or delete a record that should not be deleted. Another error might pop up while trying to connect to a database that does not exist.

Our goal in this chapter of the free database course is to introduce error handling techniques in Delphi ADO database application. You can learn about errors and exceptions (general, not database specific) in the article entitled Errors and Exceptions.

There are several approaches we can use to handle database related errors. One approach is to let Delphi show the exception message, but it is much more user friendly to try to correct the error and show some more details on the error:

  • Global exception handling allows you to create a single procedure to handle any exceptions that may occur in a program. You write a code for the OnException event of the global Application object by using the ApplicationEvents component. This code is then used to handle not just database related errors but any error that may appear while the application is running.
  • Handling dataset's specific events is an another approach. Events like OnPostError, OnEditError, OnInsertError and similar occur when an attempt to post a record, edit or insert fails. All those events are dataset specific.
  • Surrounding risky database operations with try-except and try-finally blocks, such as a call to the Execute statement of the ADOQuery object is another way to trap a possible exception.
  •    EDatabaseError, EADOError, OLE exceptions
    When developing Delphi ADO based database solutions you should be aware of the several types of exceptions. In general, information that describes the conditions of a database error can be obtained for use by an application through the use of an EDatabaseError exception. The more ADO specific exception object is the ADOError object raised when an application detects errors generated by ADO datasets.
    Finally, since ADO is based on OLE, OLE exceptions (EOLEError, EOLEException and EOLESysError) might occur, in a Delphi application, during an attempt to invoke a method or property of an OLE automation object - ADO Express (dbGO in D6) components that implement ADO in Delphi are built as wrappers around the ADO objects. When we use ADO extensions like ADOX or JRO libraries OLE exceptions may occur, too.

       Error information and management
    All the types of exceptions that may occur in a Delphi application are deriveed from the Exception class, which provides a set of properties and methods that can be used to handle error conditions in a graceful manner.

    In situations where an ADO dataset is used without any data aware components (reporting, looping through a recordset, etc) we can use exception handling blocks:

     try
       ADOTable.Open;
     except
       on E:Exception do
       begin
         MessageDlg('Error Opening Table ' + E.ClassName,
                    mtError, [mbOK], 0);
         LogError(E);
       end;
     end;
    

    In the except block, you use a series of on/do statements to check for different exceptions. When using the Exception for E your code will handle all exceptions that occur. In the MessageDlg we display the error message and the exception class (E.ClassName). For example, if you try to open a table that is exclusively opened by some other user (Table design in MS Access) you'll get an EOLEError.

    When handling dataset's specific events (for example OnPostError for ADOTable dataset) we write code for the appropriate events.

    procedure TForm1.ADOTablePostError(
      DataSet: TDataSet; 
      E: EDatabaseError;
      var Action: TDataAction);
    begin
      LogError (E); //custom error loggin procedure 
      {
      Show some message to the user 
      about the failure of the the post operation..
      }
      Action := daAbort;
    end;
    

    The Action parameter indicates how an application should respond to a database error condition. If you are able to determine the cause of the error and fix it, you use the daRetry action - Delphi will try to re-execute the Post method. The daAbort action should be specified when you handle the error (show some meaningful message) and there is no need for the exception to "go" the the global exception handler (Application.OnException). The daFial is the default action.

    If your application provides the event handler for the OnException event of the ApplicationEvents component, all the exceptions can be handled in one place:

    procedure TForm1.ApplicationEventsException
    	(Sender: TObject; E: Exception);
    begin
      LogError (E); //custom error logging procedure 
    end;
    

    The message property (of the Exception object) can be used to show a message on the screen, save the message in some log file, or combine some specific message information with our own custom message.

       Error logging procedure
    In most situations it is a good idea to have some error logging procedure that writes every error to a text file. The LogError procedure below uses the TStringList object to store information of the current error in a file named error.log (in the application folder).

    procedure LogError(E:Exception);
    var sFileName  : string;
        errLogList : TStringList;
    begin
     sFileName := ExtractFilePath(Application.EXEName) + 'error.log';
    
     errLogList := TStringList.Create;
     try
      if FileExists(sFileName) then 
         errLogList.LoadFromFile(sFileName);
      with errLogList do
      begin
       Add('Error Time Stamp: ' +
          FormatDateTime('hh:nn am/pm', Now) + 
          ' on ' + 
          FormatDateTime('mm/dd/yy', Now));
       Add('Error Class: ' + E.ClassName);
       Add('Error Message: ' + E.Message);
       SaveToFile(sFileName);
      end; //with
     finally
      errLogList.Free;
     end;
    end;
    

    When you open the error.log file with some text editor, you'll get something like:

    ...
    Error Time Stamp: 02:49 pm on 10.30.01
    Error Class: EOleException
    Error Message: Table 'djelatnici' is exclusively locked by user...
    ...

       ADO Errors collection
    Any operation involving ADOExpress components can generate one or more errors. As each error occurs, one or more Error objects are placed in the Errors collection of the ADOConnection component. You must note that error objects represent individual errors from the provider and are not ADO-specific, this means that the "same" error will be reported differently by MS Access and differently by MS SQL Server. When an error occurs, the provider is responsible for passing an error text to ADO. In Delphi, using the Errors Collection object directly is not recommended unless you are familiar with connection object operations.
    The Error property of TADOConnection component represents the Errors object and has several properties. The Description property contains the text of the error. The Number property contains the long value of the error constant. The Count property indicates the number of Error objects currently stored in the collection. To get the Description of the last error in the Errors object you can use the next statement:
    ADOConnection1.Errors.Item[ADOConnection1.Errors.Count-1].Description;

       To the next chapter
    If you need any kind of help so far, please post to the Delphi Programming Forum where all the questions are answered and beginners are treated as experts.

    DB Course Next Chapter >>
    >> From ADO Query to HTML

    ©2014 About.com. All rights reserved.