Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch block not catching exception

I have a child form that is throwing an ApplicationException in the Load event handler (intentionally for testing purposes). The parent form wraps the ChildForm.Show() method in a Try...Catch ex As Exception block. The catch block simply displays a message and closes the child form. All works as expected when debugged in visual studio 2008 (.net 3.5 sp1). However, when I run it outside of visual studio, the Catch block seems to get missed and an unhandled exception occurs. Any idea why that is?

Thank you.

Example Code:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim f2 As Form2

        f2 = New Form2

        Try
            MessageBox.Show("Opening form 2")
            f2.ShowDialog()
        Catch ex As Exception
            f2.Close()
            MessageBox.Show("Form 2 closed.")
        End Try
    End Sub

End Class

Public Class Form2

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Throw New ApplicationException("Test Form_Load")
    End Sub

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
    End Sub

End Class

Stack Trace:

 System.ApplicationException:
 Test Form_Load   at WindowsApplication1.Form2.Form2_Load(Object sender, EventArgs e)
 in UnhandledExceptionTest2\WindowsApplication1\Form2.vb
 System.Windows.Forms.Form.OnLoad(EventArgs e)
 System.Windows.Forms.Form.OnCreateControl()
 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
 System.Windows.Forms.Control.CreateControl()
 System.Windows.Forms.Control.WmShowWindow(Message& m)    at
 System.Windows.Forms.Control.WndProc(Message&> m)    at
 System.Windows.Forms.ScrollableControl.WndProc(Message&> m)    at
 System.Windows.Forms.ContainerControl.WndProc(Message&> m)    at
 System.Windows.Forms.Form.WmShowWindow(Message&> m)    at
 System.Windows.Forms.Form.WndProc(Message&> m)    at
 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&> m)    at
 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&> m)    at
 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr
 lparam)
like image 542
DCNYAM Avatar asked Dec 23 '08 17:12

DCNYAM


1 Answers

The Form.Load event behaves the same way as most other events in Windows Forms. It is dispatched by the message loop, in this case when Windows sends the WM_SHOWWINDOW message. There is an exception handler in the message loop that prevents an uncaught exception from terminating the message loop. That exception handler raises the Application.ThreadEvent event. The default event handler displays the unhandled exception dialog.

Long story short, you cannot catch an exception raised in the Load event in your button Click handler. Other than catching and handling exceptions in the Load event handler itself, very hard to do right, I'd recommend you add a public method to the form. Something like Initialize(). Move the code from your Load event into that method. Call Initialize() after calling the Show() method, exceptions are now yours to catch.

like image 198
Hans Passant Avatar answered Oct 14 '22 22:10

Hans Passant