I've been involved in an interesting post where a member wanted to create a Global Exception Handler. As an absolute purist of course, I recommend that an adequate testing phase should eradicate virtually all errors, barring those that are effected by outside elements, e.g. FileSystem, Database(s), Networking, etc.
Anyhoo, we initially started off utilising the 'AppDomain.UnhandledException' event and whilst this certainly worked in the Development Environment, if it was ran as a normal executable as either the Debug or Release build - the CLR Error Handler would appear. After some research, I came across ex-MVP's Daniel Moth's Blog entry on the subject where the ThreadException event of the Application should also be captured along with a Try..Catch statement wrapped around the 'Application.Run' statement.
Anyhoo - the good news is that it worked (tested for Framework 2.0) and here's the code for those who are interested...
Module Startup
' Main display form
Private myStartupForm As Form1
' Delegate used to marshal back to the main UI thread
Private Delegate Sub SafeApplicationThreadException(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
Sub Main()
' Initialise the startup form
myStartupForm = New Form1
' Configure the form...
' Configure AppDomain
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf AppDomain_UnhandledException
AddHandler Application.ThreadException, AddressOf Application_ThreadException
' Start the main form
TryApplication.Run(myStartupForm)
Catch ex
As Exception
' Custom handling logic
DisplayCustomErrorLogic(ex)
End TryEnd Sub
Private
Sub DisplayCustomErrorLogic(
ByVal sourceException
As Exception)
' Hide the current form
myStartupForm.Hide()
' Display the message
MsgBox(sourceException.Message.ToString)
' Exit the application (you don't have to though)
Application.Exit()
End Sub
Private
Sub Application_ThreadException(
ByVal sender
As Object,
ByVal e
As Threading.ThreadExceptionEventArgs)
' Pass to the safe exception handler
SafeApplication_ThreadException(sender, e)
End SubPrivate
Sub SafeApplication_ThreadException(
ByVal sender
As Object,
ByVal e
As Threading.ThreadExceptionEventArgs)
' Are we running on the correct thread?
If myStartupForm.InvokeRequired
Then' Invoke back to the main thread
myStartupForm.Invoke(New SafeApplicationThreadException(AddressOf SafeApplication_ThreadException), New Object() {sender, e})
Else' Custom handling logic
DisplayCustomErrorLogic(e.Exception)
End If End SubPrivate
Sub AppDomain_UnhandledException(
ByVal sender
As Object,
ByVal e
As UnhandledExceptionEventArgs)
' Custom handling logic
DisplayCustomErrorLogic(DirectCast(e.ExceptionObject, Exception))
End Sub
End Module
Note: the ThreadingException event is marshalled back to the main GUI thread, this allows any specific GUI manipulation with the original starting form if so desired.
Note 2: in order to utilise the above code, create a new module called Startup and paste the above in. When completed, open the Project Properties up and select the 'Application' tab. Ensure that the 'Enable Application Framework' checkbox is unticked and then select 'Sub Main' from the Combobox titled 'Startup Object'.
M