I made a project in VB.NET. If the application I made will produce an unwanted error, it will create a text file containing the error. I was able to do this when running it on Visual Studio but it does not work when running the separate application, the executable file found on bin/Debug.
Here's what I've done:
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?
Yes, that Catch clause is never going to catch an exception when you run this without a debugger attached. Exceptions that are raised on the UI thread are rerouted and trigger the Application.ThreadException event instead. Which by default displays a dialog, you should have noticed that when you ran it from the bin\Debug directory.
It works differently when you have a debugger attached, that dialog really gets in the way when you need to debug unhandled exceptions. So the ThreadException event is intentionally disabled and the debugger shows you where your code has crashed. Which will not happen with the code you wrote, now that Catch clause does catch the exception.
The Catch clause also will not work when your program crashed due to an unhandled exception that was raised on a worker thread, it can only see exceptions on the UI thread.
You will need a more solid approach, you can get one from the AppDomain.UnhandledException event. Which is raised for any unhandled exception, regardless of what thread it was raised on. Make your code look like this instead:
Using Debugger.IsAttached ensures that you can diagnose unhandled exceptions with the debugger. Using Application.SetUnhandledExceptionMode ensures that the dialog is never displayed and all exceptions are logged.