Most of the time, you don't know which operation will raise an exception, and you cannot (and should not) wrap each and every piece of code in a try/except block. The general approach is to let Delphi handle all the exceptions and eventually pass them to you, by handling the OnException event of the global Application object. You can do so rather easily with the ApplicationEvents component.
In the ErrorLog example, I've added to the main form an instance of the ApplicationEvents component and written a handler for its OnException event:
procedure TFormLog.LogException(Sender: TObject; E: Exception); var Filename: string; LogFile: TextFile; begin // prepares log file Filename := ChangeFileExt (Application.Exename, '.log'); AssignFile (LogFile, Filename); if FileExists (FileName) then Append (LogFile) // open existing file else Rewrite (LogFile); // create a new one try // write to the file and show error Writeln (LogFile, DateTimeToStr (Now) + ':' + E.Message); if not CheckBoxSilent.Checked then Application.ShowException (E); finally // close the file CloseFile (LogFile); end; end;
The ErrorLog example uses the text file support provided by the traditional Turbo Pascal TextFile data type. You can assign a text file variable to an actual file and then read or write it. You can find more on TextFile operations in Chapter 12 of the e-book Essential Pascal, covered in Appendix C.
In the global exceptions handler, you can write to the log, for example, the date and time of the event, and also decide whether to show the exception as Delphi usually does (executing the ShowException method of the TApplication class). By default, Delphi executes ShowException only if no OnException handler is installed. In Figure 2.8, you can see the ErrorLog program running and a sample exceptions log open in ConTEXT (a nice programmer's editor built with Delphi and available at www.fixedsys.com/context).