Click here to Skip to main content
6,305,776 members and growing! (14,869 online)
Email Password   helpLost your password?
General Programming » Exception Handling » General     Intermediate

Safe Form - Simplified Unhandled Exception Handling in Visual Basic .NET

By JSaunders

An elegant way of handling those unforeseeable exceptions.
VB, Windows, .NET 1.1, WinForms, VS.NET2003, Dev
Posted:24 Jan 2005
Updated:26 Jan 2005
Views:45,005
Bookmarked:19 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
11 votes for this article.
Popularity: 3.40 Rating: 3.27 out of 5
3 votes, 27.3%
1

2
1 vote, 9.1%
3

4
7 votes, 63.6%
5

Introduction

This article hopes to simplify two key hurdles that took me a while to get past. First, unhandled exceptions. While I'm sure that none of you ever have any of these, I seem to get them at the most inopportune times. The unfriendly Continue or Quit dialog just does wonders for your reputation and almost inevitably means a crash will be imminent while you're presenting your application, or, even worse, after releasing it. The second piece that I'd like to show you is how to simplify creating templates to work from. Inheritance could be one of the best things to ever happen to Visual Basic, so, by all means, take advantage of it.

Background

I have to mention that what led me to putting this together was a very nice component by Stratalogic Software, called SLS Exception Reporter. It's a nice way of managing any exception and works great in conjunction with this template.

Part I: Unhandled Exceptions

Even though we always hope to have everything encapsulated within nice structured Try-Catch-Finally blocks, occasionally, an error happens for no foreseeable reason. When working with Windows Forms, this raises a System.Threading.ThreadException event. There's very little that you have to actually do to handle this event.

First, create a method called OnThreadException:

Private Sub OnThreadException(ByVal sender As Object, _
                       ByVal e As ThreadExceptionEventArgs)
  ' This is where you handle the exception

  ' For Instance:

  MessageBox.Show(e.Exception.Message)
End Sub

This next part is to wire up the OnThreadException handler to the Application.ThreadException event. This should be done in the constructor of the form, before the InitializeComponent method.

Public Sub New()
MyBase.New()

  'Hook the ThreadException event to the OnThreadException method.

  AddHandler Application.ThreadException, AddressOf OnThreadException

  'This call is required by the Windows Form Designer.

  InitializeComponent()

  'Add any initialization after the InitializeComponent() call


End Sub

Now, you can choose to handle the exception in any way that you wish and be sure that the user doesn't end up with the Continue or Quit dialog. If you happen to use the Stratalogic component, you may do something like:

Private oExceptionReporter As SLSExceptionReporter

Private Sub OnThreadException(ByVal sender As Object, _
                     ByVal e As ThreadExceptionEventArgs)
  oExceptionReporter = New SLSExceptionReporter.ExceptionReporter
  oExceptionReporter.ContactEmail = "myemail@mydomain.com"
  oExceptionReporter.DisplayException(e.Exception)
End Sub

Part II: Safe Form Template

Now, let's inherit all of our forms from this one, right? Now I'm a bit lazy.. err.. efficient I mean, so I want to do this the easiest possible way. I won't go into the finer points of creating templates; instead, I'll give you one to start from. I did this using Visual Studio .NET 2003. I'm not sure what the differences would be for other versions, but if you're using 2003, browse to C:\Program Files\Microsoft Visual Studio .NET 2003\Vb7.

  1. Open VBProjectItems and create a file called SafeForm.vsz to configure your form wizard:
    VSWIZARD 6.0
    Wizard=VsWizard.VsWizardEngine.7.1
    Param="WIZARD_NAME = SafeForm"
    Param="WIZARD_UI = FALSE"
    Param="PROJECT_TYPE = VBPROJ"
  2. Next, you'll need a .vsdir file in each of the areas that you would like to have the wizard accessible from.

    In the Local Project Items and UI folders, create a file called SafeForm.vsdir. In this file, type:

    ..\SafeForm.vsz|SafeForm|#3050|10|#3051|
             {164B10B9-B200-11D0-8C61-00A0C91E29D5}|4527| |Form.vb
  3. Now, go back up to C:\Program Files\Microsoft Visual Studio .NET 2003\Vb7\VBWizards.
  4. Create a folder called SafeForm and two folders inside that called Scripts and Templates.
  5. There should be a folder called 1033 under each of these two directories.
  6. Under Templates\1033, create a file called Form.vb and paste the following code:
    #Region " Imported NameSpaces "
    Imports System
    Imports System.Threading
    #End Region
    
    ''' -----------------------------------------------------------
    
    ''' Project : ExceptionHandling
    
    ''' Class : SafeForm
    
    ''' 
    
    ''' -----------------------------------------------------------
    
    ''' <summary>
    
    ''' The SafeForm class will encapsulate methods
    
    ''' to handle unhandled exceptions from forms that
    
    ''' inherit from this class.
    
    ''' </summary>
    
    ''' <remarks>
    
    ''' </remarks>
    
    ''' <history>
    
    ''' [John Saunders] 1/21/2005 Created
    
    ''' </history>
    
    ''' -----------------------------------------------------------
    
    
    Public Class [!output SAFE_ITEM_NAME]
    Inherits System.Windows.Forms.Form
    
    #Region " Windows Form Designer generated code "
    
    Public Sub New()
      MyBase.New()
    
      'Hook the ThreadException event to the OnThreadException method
    
      AddHandler Application.ThreadException, AddressOf OnThreadException
    
      'This call is required by the Windows Form Designer.
    
      InitializeComponent()
    
      'Add any initialization after the InitializeComponent() call
    
    
    End Sub
    
    'Form overrides dispose to clean up the component list.
    
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      If disposing Then
        If Not (components Is Nothing) Then
          components.Dispose()
        End If
      End If
      MyBase.Dispose(disposing)
    End Sub
    
    'Required by the Windows Form Designer
    
    Private components As System.ComponentModel.IContainer
    
    'NOTE: The following procedure is required by the Windows Form Designer
    
    'It can be modified using the Windows Form Designer. 
    
    'Do not modify it using the code editor.
    
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
      components = New System.ComponentModel.Container()
      Me.Text = "[!output SAFE_ITEM_NAME]"
    End Sub
    
    #End Region
    
    #Region " Internal Methods "
    
    Private Sub OnThreadException(ByVal sender As Object, _
                       ByVal e As ThreadExceptionEventArgs)
    'Handle any unforeseeable exceptions here.
    
      MessageBox.Show(e.Exception.Message)
    End Sub
    
    #End Region
    
    End Class
  7. You will need a file called default.js in the Scripts\1033 folder:
    //
    
    // Copyright (c) Microsoft Corporation 2001-2002. All rights reserved.
    
    //
    
    
    function OnFinish(selProj, selObj)
    {
      var oldSuppressUIValue = true;
      try
      {
        oldSuppressUIValue = dte.SuppressUI;
        var bSilent = wizard.FindSymbol("SILENT_WIZARD");
        dte.SuppressUI = bSilent;
    
        var strItemName = wizard.FindSymbol("ITEM_NAME");
        var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");
        var strTemplateFile = strTemplatePath + "\\Form.vb";
    
        var VSProject = selProj.Object;
        var refs = VSProject.References;
        var ref;
        ref = refs.Add("System");
        ref = refs.Add("System.Data");
        ref = refs.Add("System.Drawing");
        ref = refs.Add("System.Windows.Forms");
    
        var item = AddFileToVSProject(strItemName, selProj, 
                              selObj, strTemplateFile, true);
        if( item )
        {
          item.Properties("SubType").Value = "Form";
          var editor = item.Open(vsViewKindPrimary);
          editor.Visible = true;
        }
    
        return 0;
      }
      catch(e)
      {
        switch(e.number)
        {
          case -2147221492 /* OLE_E_PROMPTSAVECANCELLED */ :
            return -2147221492;
    
          case -2147024816 /* FILE_ALREADY_EXISTS */ :
          case -2147213313 /* VS_E_WIZARDBACKBUTTONPRESS */ :
            return -2147213313;
    
          default:
            ReportError(e.description);
            return -2147213313;
        }
      }
      finally
      {
        dte.SuppressUI = oldSuppressUIValue;
      }
    }
  8. Now, start Visual Studio and create a Visual Basic .NET Windows Application.
  9. Right-click Add New Item... and you should see a new choice called "Safe Form".
  10. After adding the Safe Form to your project, make sure that all other forms inherit from SafeForm and not System.Windows.Forms.Form.

Now, all unhandled exceptions are managed each time you create a new Windows Forms project, since you will have the SafeForm template there to inherit from. You can also include any other code in your template to make starting a new project easier.

Enjoy.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

JSaunders


Member
My name is John Saunders and I am a .Net/Java Software Developer for a consulting group in Charlotte, North Carolina by day, and consultant to several startups by night. I work primarily with C# ASP.Net and SQL Server, but I also do a lot of Windows forms, Compact Framework, J2EE, and workflow development as well. Certified MCP, MCDST, MCAD & MCSD.Net and, oh yea, I also jump out of airplanes. Smile
Occupation: Web Developer
Location: United States United States

Other popular Exception Handling articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 10 of 10 (Total in Forum: 10) (Refresh)FirstPrevNext
GeneralBrilliant Idea! PinmemberDigiOz Multimedia12:12 5 May '08  
GeneralSLS Exception Reporter no longer available PinmemberMisterT996:19 2 Jun '07  
AnswerRe: SLS Exception Reporter no longer available PinmemberPandaWood19:00 29 Jul '08  
Generaldebugging pocket PinmemberRenatoSuga4:24 4 Dec '06  
AnswerRe: debugging pocket PinmemberJSaunders5:54 4 Dec '06  
GeneralYou god like individual Pinmemberwheelibin7:48 12 Sep '06  
GeneralEven simpler PinmemberPinx13:59 8 Feb '05  
GeneralDebug PinmemberSerge Baltic4:55 25 Jan '05  
GeneralRe: Debug PinmemberJSaunders5:12 25 Jan '05  
GeneralRe: Debug PinmemberSerge Baltic6:19 26 Jan '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 26 Jan 2005
Editor: Smitha Vijayan
Copyright 2005 by JSaunders
Everything else Copyright © CodeProject, 1999-2009
Web13 | Advertise on the Code Project