Return to Snippet

Revision: 5563
at March 16, 2008 09:09 by sholmes


Initial Code
First you need a couple global variables:

var
  GlobalExcept: Exception;
  GlobalExceptAddr: Pointer;

And a global exception handler:

procedure TForm1.ApplicationException(Sender: TObject; E: Exception);
begin
  if E is EAccessViolation then
  begin
    // Keep the exception object from being destroyed!
    AcquireExceptionObject;
    GlobalExcept := e;
    GlobalExceptAddr := ExceptAddr;
    Application.Terminate;
  end;
end;

The rest of the magic happens in the project file (DPR)

begin
  GlobalExcept := nil;
  GlobalExceptAddr := nil;
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
  Application.Run;
  finally
    if Assigned( GlobalExcept ) then
    begin
      raise GlobalExcept at GlobalExceptAddr;
    end;
  end;
end.

Initial URL
http://www.davinciunltd.com/2007/11/crashing-like-vb/

Initial Description
« WordPress upgraded to 2.3.1CodeRage II is a Success »Crashing Like VB
I always thought Delphi’s global exception handler was a great feature. It allows your program to continue after an otherwise unhandled exception would have caused it to terminate. Typically in a serious application you would assign your own global exception handler, or used one of the great 3rd part exception handlers like madExcept or Exceptional Magic (I love that name!) They both provide a nice dialog, stack trace, logging and reporting.

Well it turns out that if you want to be Microsoft Windows Vista Logo certified, then you need to crash your application on certain exceptions.

Applications must handle only exceptions that are known and expected, and Windows Error Reporting must not be disabled. If a fault (such as an Access Violation) is injected into an application, the application must allow Windows Error Reporting to report this crash. (from requirement 3.2 Resilient Software: Eliminate Application Failures)

Microsoft’s rational for this requirement is the ISV will receive the error report Microsoft collects for them. I guess most software developers don’t have access to tools like we do in Delphi to catch exceptions and log them for us.

So short of tossing out the Forms unit and writing everything from scratch, how can you get around the usefulness of the global exception handler.

My first thought was to create a custome application exception handler by placing a TApplicationEvents on your main form and assigning the OnException event. In the event include the line

 raise e;
This will pass an exception up to the operating system and terminate your application, at least when I tested it in Delphi 2007. When I tried it in Delphi 7, it didn’t work right.

A more elegant and involved solution:

Initial Title
Global Exception Handling

Initial Tags


Initial Language
Pascal