Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  How To Handle Unhandled Exceptions
How To Handle Unhandled Exceptions
by John Spano | Published  11/23/2002 | .NET Framework | Rating:
John Spano

John Spano cofounder and CTO of NeoTekSystems, a Greenville, South Carolina technology consulting company. NeoTekSystems offers IT consulting, custom programming, web design and web hosting. We specialize in Microsoft .Net enterprise development and business design.

I have six years of experience in software architecture. My primary focus is on Microsoft technologies, and I have been involved in .NET since beta 1. I currently hold a MCSD certification, 2 MCTS's (Windows, Web) a MCPD in Distributed, 2 MCITP's, a Microsoft MVP, and have won the Helper of the Month contest for July 2002 in the devCity.NET forums.

Corporate URL: www.NeoTekSystems.com
Primary email: JSpano@NeoTekSystems.com
Alternate email: Jspano@devcity.net.

 

View all articles by John Spano...
How To Handle Unhandled Exceptions

VB.NET has a cool feature that lets you catch any unhandled exception in your programs. To set up this functionality, you have to add 2 subs that handle the exceptions, and 2 event handler definitions.

Code:

'The 2 event handlers
  'add an unhandled exceptions handler
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
  'for regular unhandled stuff
AddHandler currentDomain.UnhandledException, AddressOf MYExceptionHandler
  'for threads behind forms
AddHandler Application.ThreadException, AddressOf MYThreadHandler

Now .NET will call the 2 above functions when an Exception occurs and you don't have a Try..Catch block.

Code:
'The 2 functions
Private Sub MYExceptionHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
  'What I normally do here is call a form I have created that resembles the Microsoft Unhandled
  'Exceptions Form. It says sorry for the blow up, an error report was created, do you want to
  'send it to my company etc. You can get information off of the variable e for the error report.
End Sub

Private Sub UHThreadEX(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
  'What I normally do here is call a form I have created that resembles the Microsoft Unhandled
  'Exceptions Form. It says sorry for the blow up, an error report was created, do you want to
  'send it to my company etc. You can get information off of the variable e for the error report.
End Sub

To test use this:

Code:
Module Mod1

  Public Sub Main
    'The 2 event handlers
    'add an unhandled exceptions handler
    Dim currentDomain As AppDomain = AppDomain.CurrentDomain
    'for regular unhandled stuff
    AddHandler currentDomain.UnhandledException, AddressOf MYExceptionHandler
    'for threads behind forms
    AddHandler Application.ThreadException, AddressOf MYThreadHandler

    Dim X as Integer
    X = 5
    X = X / 0 'throws exception will be caught by subs below.
  End Sub

  Private Sub MYExceptionHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
    Dim EX As Exception
    EX = e.ExceptionObject
    Console.WriteLine(EX.StackTrace)
  End Sub

  Private Sub MYThreadHandler(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
    Console.WriteLine(e.Exception.StackTrace)
  End Sub
End Module

This article was originally posted as devCity.NET Forums FAQ - http://www.devcity.net/forums/faq.asp?fid=15#TID5038

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:4.38709677419355 out of 5
 31 people have rated this page
Article Score14070
Related Articles
Comments    Submit Comment

Comment #1  (Posted by Steve C on 11/26/2002)

I'm new to VB.NET, so please excuse if there is an obvious answer

I've created a new console application, and pasted in the code from the "To test use this" section, but the IDE is showing an error on the line
AddHandler Application.ThreadException, AddressOf MYThreadHandler
that "Name 'Application' is not declared"
 
Comment #2  (Posted by Richard on 11/26/2002)

When it hit the exception here is what happened:

Error message: An unhandled exception ... Additional information: Arithmetic operation resulted in an overflow.

I pressed Continue

Console.WriteLine(EX.StackTrace) message "at Unhandled.Mod1.Main() in path\Module1.vb:line 14 ..."

If you are not running this from an IDE there is a Just-In-Time Debugging message.

What did I do wrong?


 
Comment #3  (Posted by John on 11/26/2002)

For Steve C. Application is part of System.Windows.Forms. You would have to include that namespace to get it to work. I haven't tried this with console apps, but I have heard it doesn't work correctly with services. This could be the same problem. It works great with windows forms.
 
Comment #4  (Posted by John on 11/26/2002)

For Richard. On Development machines there is a registry entry that you have to change to get it to work right. The default is to ask you if you want to attach the debugger. The key is :

HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting

change the value to 1 This will return control to your code.

Sorry for the lack of info. This started out as a quick faq in the forums.
 
Comment #5  (Posted by Dev on 12/10/2002)

I am sorry, but I was unable to run this code.
# I created a new windows application.
# Added a module as mod1.vb
# pasted the last part of the code to that.
# Now confused, where to put the rest two part of the code.

Please help. I am in great need......

Thanks,
 
Comment #6  (Posted by John Spano on 12/10/2002)

Take the whole piece of code listed above and put it in a module. Change your project startup property to sub main instead of form 1. Replace the following code

Dim X as Integer
X = 5
X = X / 0 'throws exception will be caught by subs below.

with
dim frm as form1
frm = new form1
frm.showdialog()

this will start your application with sub main and then register the unhandled exception functions, then show form 1. The 2 unhandled functions should catch all unhandled errors. Note the above post also about the registry.


 
Comment #7  (Posted by an unknown user on 01/30/2005)
Rating
it's very good. i have no words to explain.
 
Comment #8  (Posted by Michael Rybicki on 04/29/2005)
Rating
We use this extensively in our system however we ran into a big problem - maybe someone can offer suggestions. When we run our code on a Terminal Server (win 2003) a JIT debugger tries launching instead of letting our error handler do it. I set the following registry key to 0, 1, & 2 and couldn't get my exception handler to kick in: HKLM\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting

But here's the kicker: It only tries to launch the JIT debugger if the user is NOT an admin. For Admin users on the machine - this code owrks perfectly.

HELP!
 
Comment #9  (Posted by an unknown user on 05/04/2005)
Rating
Outstanding! I knew there had to be a way to do this but haven't come accross it until now. One of our clients previously had vs.net but removed it. The registry entry was still set to run JIT so we'd get an error running JIT instead of seeing the real error. THANKS!
 
Comment #10  (Posted by an unknown user on 09/16/2005)
Rating
Outstanding! Thanks very much. This actually helped me to solve a big problem for my new company which I just started working with a week ago!! Thanks again.
 
Comment #11  (Posted by an unknown user on 09/16/2005)
Rating
Outstanding! Thanks very much. This actually helped me to solve a big problem for my new company which I just started working with a week ago!! Thanks again.
 
Comment #12  (Posted by an unknown user on 01/17/2006)
Rating
It was useful, but it should be proofread. For example, you set a handler to "MYThreadHandler" but then you call the sub "UHThreadEX" I can be confusing to the less aware
 
Comment #13  (Posted by Kiran Kumar on 02/03/2006)
Rating
Code snippet is very good.
But i need to log my form name, method name from where the error occurred. How to do that? Thanks in advance.
 
Comment #14  (Posted by John Spano on 02/03/2006)
Rating
You can get the full stack trace from the exception itself. Check out the source and stacktrace properties of the exception object.
 
Comment #15  (Posted by an unknown user on 04/19/2006)
Rating
It helped me a lot.thank you very much
 
Comment #16  (Posted by an unknown user on 06/02/2006)
Rating
In addition to your article about exceptionhandling i would like to add one thing:

With the following you easely get all the info you need...
note: ex is the exception

Dim sFaultInfo As String = ""

Dim sArrTrace As String() = ex.StackTrace.Split(vbNewLine)
For i As Integer = 0 To sArrTrace.Length - 1
Dim sPartOfTheTrace As String = sArrTrace(i)
Dim sAssembly As String = My.Application.Info.AssemblyName
If sPartOfTheTrace.Contains(sAssembly) Then
sFaultInfo = sArrTrace(i).Trim()
Exit For
End If
Next

sFaultInfo = ex.Message & sFaultInfo
 
Comment #17  (Posted by an unknown user on 08/02/2006)
Rating
Spent hours looking for a solution to my problem... then this turned out to be exactly what I needed.
By the way, there's a bit of a typo:
UHThreadEX appears instead of MYExceptionHandler in one place - so some of the code doesn't work if you simply cut and paste into your app.
Thanks!
 
Comment #18  (Posted by an unknown user on 09/21/2006)
Rating
This info is hard to find on the net. Tnaks a lot!
 
Comment #19  (Posted by an unknown user on 01/17/2007)
Rating
It's really good, but I wanted something else. When a UnHandled exception occurs, the sub(s) executes, then same exception is propageted to the program. The exception itself doesn't go away. I want, after writing/showing error message, program continues to execute. Not sure if I am asking too much. Can it be possible?
 
Comment #20  (Posted by an unknown user on 01/17/2007)
Rating
I see what you want, but from good programming practices you do NOT want this to happen. If you end up catching this type of error, that means you didn't think of it. It catches unhandled exceptions. Your program is in a bad state now that you didn't know about. It should end and you should restart the program.
 
Comment #21  (Posted by developer281 on 01/25/2007)
Rating
I have a .Net dll for which I want to add the unhandled exception and thread handlers. I added both as you have on the website and I put msg boxes in them to see if the code goes through them however they don't seem to get called.

My dll is not attached to a form, it is just an application that is constanty executing but does not have a gui or console attached to it... is that why the handlers don't get called?

I'm not sure if dlls behave differently than exes when it comes to unhandled exceptions.

any insight you can give is appreciated
 
Comment #22  (Posted by an unknown user on 01/30/2007)
Rating
This is fantastic, you saved me heaps of time
 
Comment #23  (Posted by an unknown user on 04/19/2007)
Rating
Hey thanks guys, this is very helpfull, i used your idea on the AppDomain in my component and Comment #4 (Posted by John on 11/26/2002) helped me alot also. Thanks again!

Pablo

'NOTE: If running on a development machine, this will not work properly unless HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting is set to 1
Imports System.Windows.Forms
Imports System.Data.SqlClient
Imports ZipsCommon

Public Class ErrorHandler

#Region " Variables "
Private Shared mHasBeenInited As Boolean = False
#End Region

#Region " Constructor Lockout "
Private Sub New()
End Sub
#End Region

#Region " Event Handler "
Private Shared Sub ThreadHandler(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs)
LogException(e.Exception, True)
End Sub

Private Shared Sub UnhandledHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
LogException(e.ExceptionObject, True)
End Sub
#End Region

#Region " Subs "
Public Shared Sub Init()
If mHasBeenInited Then Exit Sub
AddHandler Application.ThreadException, AddressOf ThreadHandler
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledHandler
mHasBeenInited = True
End Sub

Public Shared Sub LogException(ByVal ex As Exception)
LogException(ex, False)
End Sub

Private Shared Sub LogException(ByVal ex As Exception, ByVal wasUnhandled As Boolean)
Try
'NOTE: To avoid circular dependencys, all errors will be loged to the database at ->SetupInfo.DBConnStr
Dim cmd As SqlCommand = New SqlCommand("NewError", New SqlConnection(SetupInfo.DBConnStr))
With cmd
.CommandType = CommandType.StoredProcedure

.Parameters.AddWithValue("@StoreID", SetupInfo.StoreID)
.Parameters.AddWithValue("@ExMsg", ex.Message)
.Parameters.AddWithValue("@StckTrc", ex.StackTrace)
.Parameters.AddWithValue("@WasUnhandled", wasUnhandled)

.Connection.Open()
.ExecuteNonQuery()
.Connection.Close()
.Connection.Dispose()
.Dispose()
End With
Catch ex2 As Exception
End Try
End Sub

Public Shared Sub Dispose()
If Not mHasBeenInited Then Exit Sub

RemoveHandler Application.ThreadException, AddressOf ThreadHandler
RemoveHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledHandler

mHasBeenInited = False
End Sub
#End Region

End Class
 
Comment #24  (Posted by an unknown user on 09/14/2007)
Rating
1)overflow exception unhandled
2)arithmatic operation is overflow
 
Comment #25  (Posted by an unknown user on 01/12/2008)
Rating
liittle info

just shaiser
 
Comment #26  (Posted by an unknown user on 04/30/2008)
Rating
Amazing. I figured out certain EX.Message and checked for it, and it saved my life. Great code, great example. Very clear
 
Comment #27  (Posted by an unknown user on 05/09/2008)
Rating
the handler catches the exception, but it doesn't "clear" the error, it continues to happen.
 
Sponsored Links