Try / Catch on Application.Run works in the debugger, but does not work when the application starts

I made a project in VB.NET. If the application I made leads to an unwanted error, it will create a text file containing the error. I was able to do this when starting in Visual Studio, but it does not work when starting a separate application, the executable file found in bin / Debug.

Here is what I did:

Sub Main(ByVal ParamArray args() As String) Try System.Windows.Forms.Application.Run(New Form1) Catch ex As Exception WriteErrorLogs(ex) End Try End Sub Sub WriteErrorLogs(Byval ex As Exception) ' create a textfile the write x.Message, x.Source, x.ToString Dim dnow As String = Now.ToString Dim filename As String = "Error " & removeInvalidChars(dnow) Dim saveto As String = New IO.FileInfo("Errors/" & filename).FullName & ".txt" Dim title As String = ex.Message Dim stacktrce As String = ex.StackTrace If Not IO.Directory.Exists(New IO.DirectoryInfo("Errors").FullName) Then IO.Directory.CreateDirectory("Errors") Dim fw As New IO.StreamWriter(saveto, False, System.Text.Encoding.UTF8) fw.WriteLine(title) fw.WriteLine() fw.WriteLine(stacktrce) fw.Close() End Sub Private Function removeInvalidChars(ByRef s As String) Dim invalidChars() As Char = "\/:*?""<>|".ToCharArray For Each i As Char In invalidChars s = s.Replace(i, ".") Next Return s End Function 

Is there a better solution for this?

+4
error-handling
source share
1 answer
  Try System.Windows.Forms.Application.Run(New Form1) Catch ex As Exception WriteErrorLogs(ex) End Try 

Yes, this Catch clause will never catch an exception if you run it without a debugger attached. Exceptions that occur in the user interface thread are redirected and throw an Application.ThreadException event instead. What the dialog box displays by default, you should have noticed that when you started it from the bin \ Debug directory.

It works differently when you have a debugger installed, this dialog really gets in the way when you need to debug unhandled exceptions. Therefore, the ThreadException event is intentionally disabled, and the debugger shows you where your code crashed. What won't happen with the code you wrote now that the Catch clause blocks the exception.

The Catch clause will also not work if your program crashes due to an unhandled exception that has been raised in the workflow, it can only see exceptions in the user interface thread.

You will need a stronger approach, you can get it from the AppDomain.UnhandledException event. Which is caused for any unhandled exception, no matter what thread it was raised to. Make your code look like this:

 Module Module1 Public Sub Main(ByVal args() As String) Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) If Not System.Diagnostics.Debugger.IsAttached Then Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException) AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf LogUnhandledExceptions End If Application.Run(New Form1()) End Sub Private Sub LogUnhandledExceptions(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs) Dim ex = DirectCast(e.ExceptionObject, Exception) '' Log or display ex.ToString() ''... Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex)) End Sub End Module 

Using Debugger.IsAttached ensures that you can diagnose unhandled exceptions with a debugger. Using Application.SetUnhandledExceptionMode ensures that the dialog is never displayed and all exceptions are logged.

+8
source share

All Articles