OK, how does someone stupid proof an unhandled exception handler? As you can see below, I am trapping two events with these handlers.
Public Sub OnThreadException( _
ByVal sender As Object, _
ByVal e As System.Threading.ThreadExceptionEventArgs)
Public Sub OnUnhandledException( _
ByVal sender As Object, _
ByVal e As System.UnhandledExceptionEventArgs)
I think these are correct for a WinForms app. I check the event args for Nothing and e.Empty before processing since this seems prudent. Within the CommonHandler routine, I assume an exception there should lead to application termination. Otherwise, I proceed with setting up and displaying and ExceptionForm (not included here) that acts as the exception display in place of the standard .NET dialog.
I am a little uneasy about this part:
CType(e.ExceptionObject, System.Exception)
I have not been able to get the IDE to let me test it yet. I am still hopeful though. Again, logging is stubbed out for later modification. Most of this class is pretty easy and seems too cover what is needed, but are there any lessons learned out there that can improve or modify it?
===== Start File UnhandledException.vb =====
Option Explicit On
Option Strict On
Imports System.Windows.Forms
Namespace Exception
Public Class GlobalExceptionHandler
#Region " Class Data "
Private m_UnhandledExceptionHandlerAdded As Boolean = False
Private m_Text As String
Private currentDomain As AppDomain = AppDomain.CurrentDomain
#End Region
#Region " Event Handlers "
Public Sub OnThreadException( _
ByVal sender As Object, _
ByVal e As System.Threading.ThreadExceptionEventArgs)
m_Text = "Thread Exception"
If ((e Is Nothing) Or (e Is e.Empty)) Then ErrorExit(m_Text)
CommonHandler(sender, e.Exception, m_Text)
End Sub
Public Sub OnUnhandledException( _
ByVal sender As Object, _
ByVal e As System.UnhandledExceptionEventArgs)
m_Text = "Unhandled Exception"
If ((e Is Nothing) Or (e Is e.Empty)) Then ErrorExit(m_Text)
CommonHandler(sender, CType(e.ExceptionObject, System.Exception), m_Text)
End Sub
#End Region
#Region " Private Routines "
Private Sub CommonHandler( _
ByVal sender As Object, _
ByVal e As System.Exception, _
ByVal text As String)
Dim result As DialogResult = System.Windows.Forms.DialogResult.Cancel
If (System.Configuration.ConfigurationSettings.AppSettings.Get _
("DisplayExceptions") = "Developer") Then
' Show Developer information
Try
Dim frm As New ExceptionForm(e, True)
result = frm.Show(True)
Catch exLocal As System.Exception
' Since we have an exception in our exception handler, we Exit
Try
DoLogging(String.Empty)
MessageBox.Show( _
"Fatal Error - Unhandled error in GlobalExceptionHandler" & _
vbCrLf & vbCrLf & exLocal.GetBaseException.ToString, _
"Fatal Error", _
MessageBoxButtons.OK, _
MessageBoxIcon.Stop)
Finally
Application.Exit()
End Try
End Try
Else ' If not Developer
' Show User information
DoLogging(String.Empty)
'TODO: Handle user display case
MessageBox.Show("User Friendly Message")
End If
' Exits the program when the user clicks Abort
If (result = System.Windows.Forms.DialogResult.Abort) Then Application.Exit()
End Sub
Private Sub ErrorExit(ByVal message As String)
Try
DoLogging(String.Empty)
MessageBox.Show( _
"Fatal Error - Empty EventArgs in " + message + " - Exiting the program", _
"Fatal Error", _
MessageBoxButtons.OK, _
MessageBoxIcon.Stop)
Finally
Application.Exit()
End Try
End Sub
#End Region
#Region " Handler Control "
Public Sub AddNewHandler()
If (Not m_UnhandledExceptionHandlerAdded) Then
AddHandler _
System.Windows.Forms.Application.ThreadException, _
New System.Threading.ThreadExceptionEventHandler(AddressOf OnThreadException)
AddHandler _
AppDomain.CurrentDomain.UnhandledException, _
AddressOf OnUnhandledException
m_UnhandledExceptionHandlerAdded = True
DoLogging("AddHandler GlobalExceptionHandler")
End If
End Sub
Public Sub RemoveCurrentHandler()
If (m_UnhandledExceptionHandlerAdded) Then
RemoveHandler _
System.Windows.Forms.Application.ThreadException, _
New System.Threading.ThreadExceptionEventHandler(AddressOf OnThreadException)
RemoveHandler _
currentDomain.UnhandledException, _
AddressOf OnUnhandledException
m_UnhandledExceptionHandlerAdded = False
DoLogging("RemoveHandler GlobalExceptionHandler")
End If
End Sub
#End Region
Private Sub DoLogging(ByVal message As String)
' Future expansion
End Sub
End Class
End Namespace
===== End File UnhandledException.vb =====