The Application.OnException
handler is only called for unhandled exceptions.
An unhandled exception is one where no try..except
block has caught the exception or where it has been caught and then re-raised.
Using some trivial examples to demonstrate, let's assume that this is virtually the only code in the application and that there are no other exception handlers...
try
a := 42 / 0;
except
on EDivisionByZero do
begin
Log.i('Silly division by zero error has been logged');
raise;
end;
end;
In this case, the exception is caught but the application has no strategy for handling the exception so simply logs that it has occurred and then re-raises the exception. Execution will continue in any outer except
block. If there are none, or if any that may exist also re-raise the exception, then eventually the exception will reach the Application.OnException
handler.
But an exception handler might not need to re-raise an exception:
try
a := 42 / 0;
except
on EDivisionByZero do
a := 0;
end;
In this case, the exception handler handles the division by zero and does not re-raise it since the code is happy to proceed with a result of zero in that case (unlikely, but this is just an example).
Since the exception is not re-raised, execution proceeds (after the try..except
block) as if the exception had never happened in the first place. Your Application.OnException
will never know about it.
In summary: Application.OnException
is your last chance to deal with an unhandled exception. It is not the first opportunity to respond to any exception.
Intercepting exceptions at the moment that they occur, before any application code has had an opportunity to react or deal with them is possible, but is pretty advanced stuff and no simple mechanism is provided "out of the box".
Fortunately there are 3rd party libraries you can use that may provide the capabilities you are seeking to introduce into your application.
A popular one for Delphi which you might wish to check out is madExcept.