Skip to content

Commit 9f99090

Browse files
committed
Error report generation refactor
- More reorganization in WinNUT_Globals.vb. Renaming some variables for clarity. - Updated dependencies - Refactor error report generation. Attempts to account for more error conditions and ensure a report can be generated.
1 parent 1c73454 commit 9f99090

File tree

4 files changed

+90
-110
lines changed

4 files changed

+90
-110
lines changed

WinNUT_V2/WinNUT-Client/ApplicationEvents.vb

Lines changed: 58 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
Imports System.IO
1111
Imports Microsoft.VisualBasic.ApplicationServices
12+
Imports Newtonsoft.Json
1213
Imports WinNUT_Client_Common
1314

1415
Namespace My
@@ -19,23 +20,23 @@ Namespace My
1920
' StartupNextInstance : Déclenché lors du lancement d'une application à instance unique et si cette application est déjà active.
2021
' NetworkAvailabilityChanged : Déclenché quand la connexion réseau est connectée ou déconnectée.
2122
Partial Friend Class MyApplication
23+
24+
2225
Private CrashBug_Form As New Form
2326
Private BtnClose As New Button
2427
Private BtnGenerate As New Button
2528
Private Msg_Crash As New Label
2629
Private Msg_Error As New TextBox
30+
Private exception As Exception
2731

2832
Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
29-
'Init WinNUT Variables
3033
Init_Globals()
31-
LogFile.LogTracing("Init Globals Variables Complete", LogLvl.LOG_DEBUG, Me)
34+
LogFile.LogTracing("MyApplication_Startup complete.", LogLvl.LOG_DEBUG, Me)
3235
End Sub
3336

3437
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
3538
e.ExitApplication = False
36-
37-
Dim Frms As New FormCollection
38-
Frms = Application.OpenForms()
39+
exception = e.Exception
3940

4041
With Msg_Crash
4142
.Location = New Point(6, 6)
@@ -49,19 +50,12 @@ Namespace My
4950
.Size = New Point(470, 100)
5051
End With
5152

52-
Dim Exception_data = BuildExceptionString(e.Exception)
53-
54-
If e.Exception.InnerException IsNot Nothing Then
55-
Exception_data &= vbNewLine & "InnerException present:" & vbNewLine
56-
Exception_data &= BuildExceptionString(e.Exception.InnerException)
57-
End If
58-
5953
With Msg_Error
6054
.Location = New Point(6, 110)
6155
.Multiline = True
6256
.ScrollBars = ScrollBars.Vertical
6357
.ReadOnly = True
64-
.Text = Exception_data.ToString()
58+
.Text = e.Exception.ToString()
6559
.Size = New Point(470, 300)
6660
End With
6761

@@ -95,97 +89,82 @@ Namespace My
9589

9690
AddHandler BtnClose.Click, AddressOf Application.Close_Button_Click
9791
AddHandler BtnGenerate.Click, AddressOf Application.Generate_Button_Click
98-
AddHandler CrashBug_Form.FormClosing, AddressOf Application.CrashBug_FormClosing
9992

10093
CrashBug_Form.Show()
10194
CrashBug_Form.BringToFront()
10295
WinNUT.HasCrashed = True
10396
End Sub
10497

105-
''' <summary>
106-
''' Generate a friendly message describing an exception.
107-
''' </summary>
108-
''' <param name="ex">The exception that will be read for the message.</param>
109-
''' <returns>The final string representation of the exception.</returns>
110-
Private Function BuildExceptionString(ex As Exception) As String
111-
Dim retStr = String.Empty
98+
Private Shared Function GenerateCrashReport(ex As Exception) As String
99+
Dim reportStream As New StringWriter()
100+
reportStream.WriteLine("WinNUT Bug Report")
101+
reportStream.WriteLine("Generated at " + DateTime.UtcNow.ToString("F"))
102+
reportStream.WriteLine()
103+
reportStream.WriteLine("OS Version: " & Computer.Info.OSVersion)
104+
reportStream.WriteLine("WinNUT Version: " & ProgramVersion)
112105

113-
retStr &= String.Format("Exception type: {0}" & vbNewLine, ex.GetType.ToString)
114-
retStr &= String.Format("Exception message: {0}" & vbNewLine, ex.Message)
115-
retStr &= "Exception stack trace:" & vbNewLine
116-
retStr &= ex.StackTrace & vbNewLine
106+
#Region "Config output"
107+
Dim confCopy = New Dictionary(Of String, Object)
117108

118-
Return retStr
119-
End Function
109+
reportStream.WriteLine()
110+
reportStream.WriteLine("==== Parameters ====")
111+
reportStream.WriteLine()
120112

121-
Private Sub CrashBug_FormClosing(sender As Object, e As FormClosingEventArgs)
122-
End
123-
End Sub
124-
Private Sub Close_Button_Click(sender As Object, e As EventArgs)
125-
End
126-
End Sub
127-
128-
Private Sub Generate_Button_Click(sender As Object, e As EventArgs)
129-
'Generate a bug report with all essential datas
130-
Dim Crash_Report As String = "WinNUT Bug Report" & vbNewLine
131-
Dim WinNUT_Config As New Dictionary(Of String, Object)
132-
Try
133-
WinNUT_Config = Arr_Reg_Key
134-
Catch ex As Exception
135-
Crash_Report &= "ALERT: Encountered exception while trying to access Arr_Reg_Key:" & vbNewLine
136-
Crash_Report &= BuildExceptionString(ex)
137-
End Try
138-
139-
' Initialize directory for data
140-
Dim CrashLog_Dir = ApplicationData & "\CrashLog"
141-
If Not Computer.FileSystem.DirectoryExists(CrashLog_Dir) Then
142-
Computer.FileSystem.CreateDirectory(CrashLog_Dir)
143-
End If
144-
145-
Dim CrashLog_Filename As String = "Crash_Report_" & Format(Now, "dd-MM-yyyy") & "_" &
146-
String.Format("{0}-{1}-{2}.txt", Now.Hour.ToString("00"), Now.Minute.ToString("00"), Now.Second.ToString("00"))
147-
148-
149-
150-
Crash_Report &= "Os Version : " & Computer.Info.OSVersion & vbNewLine
151-
Crash_Report &= "WinNUT Version : " & Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString & vbNewLine
152-
153-
Crash_Report &= vbNewLine & "WinNUT Parameters : " & vbNewLine
154-
If WinNUT_Config.Count > 0 Then
155-
' Prepare config values by removing sensitive information.
113+
' Censor any identifying information
114+
If Arr_Reg_Key IsNot Nothing AndAlso Arr_Reg_Key.Count > 0 Then
156115
For Each kvp As KeyValuePair(Of String, Object) In Arr_Reg_Key
116+
Dim newVal As String
157117
Select Case kvp.Key
158118
Case "ServerAddress", "Port", "UPSName", "NutLogin", "NutPassword"
159-
WinNUT_Config.Remove(kvp.Key)
119+
newVal = "*****"
120+
Case Else
121+
newVal = kvp.Value
160122
End Select
123+
124+
confCopy.Add(kvp.Key, newVal)
161125
Next
162-
Crash_Report &= Newtonsoft.Json.JsonConvert.SerializeObject(WinNUT_Config, Newtonsoft.Json.Formatting.Indented) & vbNewLine
163126

127+
reportStream.WriteLine(JsonConvert.SerializeObject(confCopy, Formatting.Indented))
128+
reportStream.WriteLine()
164129
Else
165-
Crash_Report &= "[EMPTY]" & vbNewLine
130+
reportStream.WriteLine("[EMPTY]")
166131
End If
132+
#End Region
133+
134+
#Region "Exceptions"
135+
reportStream.WriteLine("==== Exception ====")
136+
reportStream.WriteLine()
137+
reportStream.WriteLine(JsonConvert.SerializeObject(ex, Formatting.Indented))
138+
reportStream.WriteLine()
139+
#End Region
167140

168-
Crash_Report &= vbNewLine & "Error Message : " & vbNewLine
169-
Crash_Report &= Msg_Error.Text & vbNewLine & vbNewLine
170-
Crash_Report &= "Last Events :" & vbNewLine
141+
reportStream.WriteLine("==== Last Events ====")
171142

172-
For Each WinNUT_Event In LogFile.LastEvents
173-
Crash_Report &= WinNUT_Event & vbNewLine
174-
Next
143+
LogFile.LastEvents.Reverse()
144+
reportStream.WriteLine()
145+
reportStream.WriteLine(JsonConvert.SerializeObject(LogFile.LastEvents, Formatting.Indented))
175146

176-
Computer.Clipboard.SetText(Crash_Report)
147+
Return reportStream.ToString()
148+
End Function
149+
150+
Private Sub Generate_Button_Click(sender As Object, e As EventArgs)
151+
Dim logFileName = "CrashReport_" + DateTime.Now.ToString("s").Replace(":", ".") + ".txt"
152+
Dim report = GenerateCrashReport(exception)
153+
154+
Computer.Clipboard.SetText(report)
177155

178-
Dim CrashLog_Report As StreamWriter
179-
CrashLog_Report = Computer.FileSystem.OpenTextFileWriter(CrashLog_Dir & "\" & CrashLog_Filename, True)
180-
CrashLog_Report.WriteLine(Crash_Report)
156+
Directory.CreateDirectory(TEMP_DATA_PATH)
157+
Dim CrashLog_Report = New StreamWriter(Path.Combine(TEMP_DATA_PATH, logFileName))
158+
CrashLog_Report.WriteLine(report)
181159
CrashLog_Report.Close()
182160

183161
' Open an Explorer window to the crash log.
184-
' Dim fullFilepath As String = CrashLog_Dir & "\" & CrashLog_Filename
185-
' If WinNUT IsNot Nothing Then
186-
Process.Start(CrashLog_Dir)
187-
' End If
162+
Process.Start(TEMP_DATA_PATH)
188163
End
189164
End Sub
165+
166+
Private Sub Close_Button_Click(sender As Object, e As EventArgs)
167+
CrashBug_Form.Close()
168+
End Sub
190169
End Class
191170
End Namespace

WinNUT_V2/WinNUT-Client/WinNUT-client.vbproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,10 @@
396396
</ItemGroup>
397397
<ItemGroup>
398398
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
399-
<Version>7.1.2</Version>
399+
<Version>7.1.3</Version>
400400
</PackageReference>
401401
<PackageReference Include="Newtonsoft.Json">
402-
<Version>13.0.1</Version>
402+
<Version>13.0.3</Version>
403403
</PackageReference>
404404
</ItemGroup>
405405
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />

WinNUT_V2/WinNUT-Client/WinNUT.vb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ Public Class WinNUT
8686
Private Event RequestConnect()
8787

8888
Private Sub WinNUT_Load(sender As Object, e As EventArgs) Handles MyBase.Load
89-
' Make sure we have an app directory to write to.
90-
' SetupAppDirectory()
91-
92-
AddHandler Microsoft.Win32.SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
93-
AddHandler RequestConnect, AddressOf UPS_Connect
94-
9589
'Add Main Gui's Strings
9690
StrLog.Insert(AppResxStr.STR_MAIN_OLDINI_RENAMED, My.Resources.Frm_Main_Str_01)
9791
StrLog.Insert(AppResxStr.STR_MAIN_OLDINI, My.Resources.Frm_Main_Str_02)
@@ -273,6 +267,9 @@ Public Class WinNUT
273267
HasFocus = False
274268
End If
275269

270+
AddHandler Microsoft.Win32.SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
271+
AddHandler RequestConnect, AddressOf UPS_Connect
272+
276273
LogFile.LogTracing(String.Format("{0} v{1} completed initialization.", My.Application.Info.ProductName, My.Application.Info.Version),
277274
LogLvl.LOG_NOTICE, Me)
278275
End Sub
@@ -837,7 +834,7 @@ Public Class WinNUT
837834
' Setup logging preferences
838835
If Arr_Reg_Key.Item("UseLogFile") Then
839836
LogFile.LogLevelValue = Arr_Reg_Key.Item("Log Level")
840-
LogFile.InitializeLogFile(ApplicationData)
837+
LogFile.InitializeLogFile(ApplicationDataPath)
841838
ElseIf LogFile.IsWritingToFile Then
842839
LogFile.DeleteLogFile()
843840
End If

WinNUT_V2/WinNUT-Client_Common/WinNUT_Globals.vb

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,40 @@ Public Module WinNUT_Globals
1313

1414
#Region "Constants/Shareds"
1515

16+
Public ReadOnly ProgramName = My.Application.Info.ProductName
17+
Public ReadOnly LongProgramName = My.Application.Info.Description
18+
Public ReadOnly ProgramVersion = My.Application.Info.Version.ToString()
19+
Public ReadOnly ShortProgramVersion = ProgramVersion.Substring(0, ProgramVersion.IndexOf(".", ProgramVersion.IndexOf(".") + 1))
20+
Public ReadOnly GitHubURL = My.Application.Info.Trademark
21+
Public ReadOnly Copyright = My.Application.Info.Copyright
22+
23+
#Region "File Directories"
24+
25+
Private ReadOnly DATA_DIRECTORY_NAME = "WinNUT-Client"
26+
Private ReadOnly TEMP_FOLDER = Path.GetTempPath() + DATA_DIRECTORY_NAME
27+
1628
#If DEBUG Then
1729
Public ReadOnly IsDebugBuild = True
1830
' If debugging, keep any generated data next to the debug executable.
19-
Private ReadOnly DESIRED_DATA_PATH As String = Path.Combine(Environment.CurrentDirectory)
31+
Private ReadOnly DESIRED_DATA_PATH As String = Path.Combine(Environment.CurrentDirectory, DATA_DIRECTORY_NAME)
2032
#Else
21-
Public ReadOnly IsDebugBuild = False
22-
Private ReadOnly DESIRED_DATA_PATH As String = Environment.GetFolderPath(
23-
Environment.SpecialFolder.ApplicationData)
33+
Public ReadOnly IsDebugBuild = False
34+
Private ReadOnly DESIRED_DATA_PATH As String = Path.Combine(Environment.GetFolderPath(
35+
Environment.SpecialFolder.ApplicationData), DATA_DIRECTORY_NAME)
2436
#End If
2537

26-
Private ReadOnly FALLBACK_DATA_PATH = Path.GetTempPath()
27-
Private ReadOnly DATA_DIRECTORY_NAME = "WinNut-Client"
38+
Public ReadOnly TEMP_DATA_PATH = Path.Combine(Path.GetTempPath(), DATA_DIRECTORY_NAME)
2839

29-
Public ReadOnly ProgramName = My.Application.Info.ProductName
30-
Public ReadOnly LongProgramName = My.Application.Info.Description
31-
Public ReadOnly ProgramVersion = Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString
32-
Public ReadOnly ShortProgramVersion = ProgramVersion.Substring(0, ProgramVersion.IndexOf(".", ProgramVersion.IndexOf(".") + 1))
33-
Public ReadOnly GitHubURL = My.Application.Info.Trademark
34-
Public ReadOnly Copyright = My.Application.Info.Copyright
40+
#End Region
3541

36-
Public IsConnected = False
37-
Public ApplicationData As String
42+
Public ApplicationDataPath = TEMP_DATA_PATH
3843
Public WithEvents LogFile As Logger = New Logger(LogLvl.LOG_DEBUG)
39-
Public AppIcon As Dictionary(Of Integer, Drawing.Icon)
4044
Public StrLog As New List(Of String)
4145

4246
#End Region
4347

44-
45-
4648
Public Sub Init_Globals()
47-
ApplicationData = GetAppDirectory(DESIRED_DATA_PATH)
49+
ApplicationDataPath = GetAppDirectory(DESIRED_DATA_PATH)
4850
End Sub
4951

5052
''' <summary>
@@ -54,20 +56,22 @@ Public Module WinNUT_Globals
5456
''' <param name="requestedDir">The requested directory, with <see cref="ProgramName"/> appended to it.</param>
5557
''' <returns>The best possible option available as a writable data directory.</returns>
5658
Private Function GetAppDirectory(requestedDir As String) As String
57-
requestedDir = Path.Combine(requestedDir, DATA_DIRECTORY_NAME)
59+
Dim finalDir As String
5860

5961
Try
6062
Directory.CreateDirectory(requestedDir)
6163
LogFile.LogTracing("Successfully created or opened requested data directory for WinNUT." &
6264
vbNewLine & "requestedDir: " & requestedDir, LogLvl.LOG_DEBUG, Nothing)
63-
Return requestedDir
65+
finalDir = requestedDir
6466

6567
Catch ex As Exception
6668
LogFile.LogTracing(ex.ToString & " encountered trying to create app data directory. Falling back to temp.",
6769
LogLvl.LOG_ERROR, Nothing)
6870

69-
Directory.CreateDirectory(FALLBACK_DATA_PATH)
70-
Return FALLBACK_DATA_PATH
71+
Directory.CreateDirectory(TEMP_DATA_PATH)
72+
finalDir = TEMP_DATA_PATH
7173
End Try
74+
75+
Return finalDir
7276
End Function
7377
End Module

0 commit comments

Comments
 (0)