.Net Runtime Library for Delphi
Close
How to: Receive First-Chance Exception Notifications

The FirstChanceException event of the AppDomain interface lets you receive a notification that an exception has been thrown, before the common language runtime has begun searching for exception handlers. The event is raised at the application domain level. A thread of execution can pass through multiple application domains, so an exception that is unhandled in one application domain could be handled in another application domain. The notification occurs in each application domain that has added a handler for the event, until an application domain handles the exception. The procedures and examples in this article show how to receive first-chance exception notifications in a simple program that has one application domain, and in an application domain that you create.

Receiving First-Chance Exception Notifications in the Default Application Domain

To demonstrate first-chance exception notifications in the default application domain

  • Define an event handler for the FirstChanceException event. In this example, the event handler prints the name of the application domain where the event was handled and the exception's Message property.
Delphi
program FirstChanceException; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, CNClrLib.Host, CNClrLib.Core; var Console: _Console; FirstChangeEventPtr: TClrEventHandler; procedure FirstChanceEventHandler(ASender: _ClrObject; Args: _ClrEventArgs); stdcall; var EvtArgs: _FirstChanceExceptionEventArgs; begin EvtArgs := CoFirstChanceExceptionEventArgs.Wrap(Args.EventArgs); Console.WriteLine_17('FirstChanceException event raised in {0}: {1}', TClrAppDomain.GetCurrentDomain.FriendlyName, EvtArgs.Exception.Message); end; begin Console := CoConsole.CreateInstance; try FirstChangeEventPtr := FirstChanceEventHandler; TClrAppDomain.GetCurrentDomain.AddFirstChanceException(nil, @FirstChangeEventPtr); except on E: Exception do Console.WriteLine_15('Exception: {0}', E.Message); end; end.




  • Throw an exception and catch it. Before the runtime locates the exception handler, the FirstChanceException event is raised and displays a message. This message is followed by the message that is displayed by the exception handler.
Delphi
program ThrowArgumentException; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, CNClrLib.Host, CNClrLib.Host.Helper, CNClrLib.Core; var Console: _Console; ArgumentException: _ArgumentException; begin Console := CoConsole.CreateInstance; try ArgumentException := CoArgumentException.CreateInstance('Thrown in ' + TClrAppDomain.GetCurrentDomain.FriendlyName); raise EClrException.Create(ArgumentException.AsSystemException.AsException); except on E: EClrException do Console.WriteLine_17('ArgumentException caught in {0}: {1}', TClrAppDomain.GetCurrentDomain.FriendlyName, E.Message); end; end.


  • Throw an exception, but do not catch it. Before the runtime looks for an exception handler, the FirstChanceException event is raised and displays a message. There is no exception handler, so the application terminates.
Delphi
program FirstChanceException2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, CNClrLib.Host, CNClrLib.Host.Helper, CNClrLib.Core; var Console: _Console; ArgumentException: _ArgumentException; FirstChangeEventPtr: TClrEventHandler; procedure FirstChanceEventHandler(ASender: _ClrObject; Args: _ClrEventArgs); stdcall; var EvtArgs: _FirstChanceExceptionEventArgs; begin EvtArgs := CoFirstChanceExceptionEventArgs.Wrap(Args.EventArgs); Console.WriteLine_17('FirstChanceException event raised in {0}: {1}', TClrAppDomain.GetCurrentDomain.FriendlyName, EvtArgs.Exception.Message); end; begin Console := CoConsole.CreateInstance; try FirstChangeEventPtr := FirstChanceEventHandler; TClrAppDomain.GetCurrentDomain.AddFirstChanceException(nil, @FirstChangeEventPtr); ArgumentException := CoArgumentException.CreateInstance('Thrown in ' + TClrAppDomain.GetCurrentDomain.FriendlyName); EClrException.ThrowDotNetException(ArgumentException.AsSystemException.AsException); except on E: EClrException do Console.WriteLine_17('ArgumentException caught in {0}: {1}', TClrAppDomain.GetCurrentDomain.FriendlyName, E.Message); end; end.







If your program contains more than one application domain, you can choose which application domains receive notifications.

To receive first-chance exception notifications in an application domain that you create

  • Define an event handler for the FirstChanceException event. This example uses a static method that prints the name of the application domain where the event was handled and the exception's Message property.
Delphi
procedure FirstChanceEventHandler(ASender: _ClrObject; Args: _ClrEventArgs); stdcall; var EvtArgs: _FirstChanceExceptionEventArgs; begin EvtArgs := CoFirstChanceExceptionEventArgs.Wrap(Args.EventArgs); Console.WriteLine_17('FirstChanceException event raised in {0}: {1}', TClrAppDomain.GetCurrentDomain.FriendlyName, EvtArgs.Exception.Message); end;

Create an application domain and add the event handler to the FirstChanceException event for that application domain. In this example, the application domain is named AD1.

Delphi
... var FirstChangeEventPtr: TClrEventHandler; AppD: TClrAppDomain; begin FirstChangeEventPtr := FirstChanceEventHandler; AppD := TClrAppDomain.Create('AD1'); AppD.AddFirstChanceException(nil, @FirstChangeEventPtr); ...