How to get the whole chain of exceptions in the Application.ThreadException event handler?

I was just working on fixing exception handling in a .NET 2.0 application, and I came across some weird issue with Application.ThreadException .

I want to catch all exceptions from events behind GUI elements (like button_Click, etc.). Then I want to filter out these exceptions for lethality, for example. with some types of exceptions, the application should continue to work, and with others, exit.

In another .NET 2.0 application, I found out that by default only in debug mode exceptions actually leave a call to Application.Run or Application.DoEvents. In release mode, this does not happen, and exceptions should be "caught" using the Application.ThreadException event.

Now, however, I noticed that the exception object thrown in the ThreadExceptionEventArgs event of the .ThreadException application is always the innermost exception in the exception chain . For logging / debugging / designing, I really want the whole chain of exceptions. It is not easy to determine which external system failed, for example, when you simply throw a SocketException: when it fails, for example, an NpgsqlException, then at least you know that this is a database problem.

So, how to get to the entire chain of exceptions from this event? Is this possible, or do I need to construct excepion handling differently?

Note that I have a -sort of-have workaround using Application.SetUnhandledExceptionMode , but this is far from ideal, because I have to roll my own message loop.

EDIT: to prevent more errors, the GetBaseException () method does NOT do what I want : it just returns the innermost exception, and the only thing I already have is the innermost exception. I want to get the most external exception!

+3
source share
7 answers

( ),
, , InnerExceptions .

, :

   Private Shared Sub Test1()
      Try
         Test2()
      Catch ex As Exception
         Application.OnThreadException(New ApplicationException("test1", ex))
      End Try
   End Sub

   Private Shared Sub Test2()
      Try
         Test3()
      Catch ex As Exception
         Throw New ApplicationException("test2", ex)
      End Try
   End Sub

   Private Shared Sub Test3()
      Throw New ApplicationException("blabla")
   End Sub

Private Shared Sub HandleAppException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
...
End Sub

Sub HandleAppException Application.ThreadException. Test1().
(e As ThreadExceptionEventArgs) HandleAppException:

ThreadException http://mediasensation.be/dump/?download=ThreadException.jpg

() , InnerExceptions wil, Exception. StackTrace, :

SO.Test3() Test.vb: 166
SO.Test2() Test.vb: 159
SO.Test1() Test.vb: 151

+1

, Application.ThreadException, .

MSDN:

Windows Forms , Windows Forms. ThreadException , . , .

. , , / try/catch. , , Application.SetUnhandledExceptionMode.

+1

- . GUI . , Form.Shown, , Application.ThreadException , , Form.Load, , Application.ThreadException.

+1

Exception.GetBaseException? , Application.TreadException. , , .

exception.getbaseexception

0

Based on some information in this chain, I used UnhandledExceptionMode.ThrowException as opposed to UnhandledExceptionMode.CatchException. Then I get an exception outside of the Run () form, and that gives me a whole chain of exceptions.

0
source

According to MSDN documentation:

When overridden in a derived class, returns an exception that is the main cause of one or more subsequent exceptions.

    Public Overridable Function GetBaseException() As Exception
        Dim innerException As Exception = Me.InnerException
        Dim exception2 As Exception = Me
        Do While (Not innerException Is Nothing)
            exception2 = innerException
            innerException = innerException.InnerException
        Loop
        Return exception2
    End Function

You can use variation to analyze the chain of exceptions.

Public Sub LogExceptionChain(ByVal CurrentException As Exception)

    Dim innerException As Exception = CurrentException.InnerException
    Dim exception2 As Exception = CurrentException

    Debug.Print(exception2.Message) 'Log the Exception

    Do While (Not innerException Is Nothing)

        exception2 = innerException
        Debug.Print(exception2.Message) 'Log the Exception

        'Move to the next exception
        innerException = innerException.InnerException
    Loop

End Sub

It would hit me like exactly what you are looking for.

-1
source

Source: https://habr.com/ru/post/1696850/


All Articles