From 4a43d017c7e3ade3dfdcda37c5f0f409fd965b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Raabe?= Date: Tue, 17 Oct 2017 13:30:33 +0200 Subject: [PATCH 1/2] Add extensions methods for Exceptions to format them in a more readable manner --- .../Extensions/ExceptionExtensions.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/FlaUIRecorder/Extensions/ExceptionExtensions.cs diff --git a/src/FlaUIRecorder/Extensions/ExceptionExtensions.cs b/src/FlaUIRecorder/Extensions/ExceptionExtensions.cs new file mode 100644 index 0000000..7f317a5 --- /dev/null +++ b/src/FlaUIRecorder/Extensions/ExceptionExtensions.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlaUIRecorder.Extensions +{ + public static class ExceptionsExtensions + { + /// + /// Formats the stack trace. + /// + /// The ex. + /// The separator. + /// Formatted stack trace message. + public static string FormatStackTrace(this Exception ex, string separator) + { + var ret = new StringBuilder(); + + for (var e = ex; null != e; e = e.InnerException) + { + if (ret.Length > 0) + ret.Append(separator); + + if (string.IsNullOrEmpty(e.StackTrace)) + continue; + + // Reverse the stack trace + var parts = e.StackTrace.Split('\n'); + + for (var i = 0; i < parts.Length; i++) + parts[i] = parts[i].Trim('\r'); + + Array.Reverse(parts); + + ret.Append(string.Join(Environment.NewLine, parts)); + } + + return ret.ToString(); + } + + /// + /// Extract all inner exception messages. + /// + /// The ex. + /// + public static string FormatStackTrace(this Exception ex) + { + return FormatStackTrace(ex, + Environment.NewLine + "---[ Start of Inner Exception ]---" + + Environment.NewLine); + } + + /// + /// Extract all inner exception messages. + /// + /// The ex. + /// + public static string ErrorString(this Exception ex) + { + return ErrorString(ex, Environment.NewLine); + } + + /// + /// Extract all inner exception messages. + /// + /// The ex. + /// The separator. + /// Inner exception message. + public static string ErrorString(this Exception ex, string separator) + { + string ret = ex.Message; + + try + { + if (null != ex.InnerException) + { + ret += separator; + ret += ErrorString(ex.InnerException, separator); + } + } + catch + { + // Silent fail + } + + return ret; + } + } +} From 19e64766d5870fad3acfdad9f720f5f4153cf8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Raabe?= Date: Tue, 17 Oct 2017 13:33:21 +0200 Subject: [PATCH 2/2] Introduce exception dialog form and handle errors --- src/FlaUIRecorder/ExceptionForm.Designer.cs | 122 ++++++++++++++++++++ src/FlaUIRecorder/ExceptionForm.cs | 60 ++++++++++ src/FlaUIRecorder/ExceptionForm.resx | 120 +++++++++++++++++++ src/FlaUIRecorder/FlaUIRecorder.csproj | 10 ++ src/FlaUIRecorder/Program.cs | 41 ++++++- 5 files changed, 348 insertions(+), 5 deletions(-) create mode 100644 src/FlaUIRecorder/ExceptionForm.Designer.cs create mode 100644 src/FlaUIRecorder/ExceptionForm.cs create mode 100644 src/FlaUIRecorder/ExceptionForm.resx diff --git a/src/FlaUIRecorder/ExceptionForm.Designer.cs b/src/FlaUIRecorder/ExceptionForm.Designer.cs new file mode 100644 index 0000000..34f7a7d --- /dev/null +++ b/src/FlaUIRecorder/ExceptionForm.Designer.cs @@ -0,0 +1,122 @@ +namespace FlaUIRecorder +{ + partial class ExceptionForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtErrorMessage = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCopyError = new System.Windows.Forms.Button(); + this.chkboxShowDetails = new System.Windows.Forms.CheckBox(); + this.chkboxShowStackTrace = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // txtErrorMessage + // + this.txtErrorMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtErrorMessage.Location = new System.Drawing.Point(12, 12); + this.txtErrorMessage.Multiline = true; + this.txtErrorMessage.Name = "txtErrorMessage"; + this.txtErrorMessage.ReadOnly = true; + this.txtErrorMessage.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.txtErrorMessage.Size = new System.Drawing.Size(410, 280); + this.txtErrorMessage.TabIndex = 0; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(347, 340); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "&OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); + // + // btnCopyError + // + this.btnCopyError.Location = new System.Drawing.Point(347, 298); + this.btnCopyError.Name = "btnCopyError"; + this.btnCopyError.Size = new System.Drawing.Size(75, 23); + this.btnCopyError.TabIndex = 3; + this.btnCopyError.Text = "&Copy Error"; + this.btnCopyError.UseVisualStyleBackColor = true; + this.btnCopyError.Click += new System.EventHandler(this.BtnCopyError_Click); + // + // chkboxShowDetails + // + this.chkboxShowDetails.AutoSize = true; + this.chkboxShowDetails.Location = new System.Drawing.Point(12, 298); + this.chkboxShowDetails.Name = "chkboxShowDetails"; + this.chkboxShowDetails.Size = new System.Drawing.Size(86, 17); + this.chkboxShowDetails.TabIndex = 1; + this.chkboxShowDetails.Text = "Show &details"; + this.chkboxShowDetails.UseVisualStyleBackColor = true; + this.chkboxShowDetails.CheckedChanged += new System.EventHandler(this.ChkboxShowDetails_CheckedChanged); + // + // chkboxShowStackTrace + // + this.chkboxShowStackTrace.AutoSize = true; + this.chkboxShowStackTrace.Location = new System.Drawing.Point(104, 298); + this.chkboxShowStackTrace.Name = "chkboxShowStackTrace"; + this.chkboxShowStackTrace.Size = new System.Drawing.Size(112, 17); + this.chkboxShowStackTrace.TabIndex = 2; + this.chkboxShowStackTrace.Text = "&Show StackTrace"; + this.chkboxShowStackTrace.UseVisualStyleBackColor = true; + this.chkboxShowStackTrace.CheckedChanged += new System.EventHandler(this.ChkboxShowStackTrace_CheckedChanged); + // + // ExceptionForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(434, 374); + this.Controls.Add(this.chkboxShowStackTrace); + this.Controls.Add(this.chkboxShowDetails); + this.Controls.Add(this.btnCopyError); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.txtErrorMessage); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ExceptionForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Exception occured"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtErrorMessage; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCopyError; + private System.Windows.Forms.CheckBox chkboxShowDetails; + private System.Windows.Forms.CheckBox chkboxShowStackTrace; + } +} \ No newline at end of file diff --git a/src/FlaUIRecorder/ExceptionForm.cs b/src/FlaUIRecorder/ExceptionForm.cs new file mode 100644 index 0000000..4e9d1d2 --- /dev/null +++ b/src/FlaUIRecorder/ExceptionForm.cs @@ -0,0 +1,60 @@ +using System; +using System.Windows.Forms; + +using FlaUIRecorder.Extensions; + +namespace FlaUIRecorder +{ + public partial class ExceptionForm : Form + { + private readonly Exception _exception; + + public ExceptionForm(Exception exception) + { + InitializeComponent(); + + _exception = exception; + + DrawErrorMessage(); + } + + private string Exceptiontext + { + get + { + var details = chkboxShowDetails.Checked ? _exception.ErrorString() : string.Empty; + var stackTrace = chkboxShowStackTrace.Checked ? _exception.FormatStackTrace() : string.Empty; + var detailedErrorMessage = string.Format("{0}{1}{2}{1}{3}{1}{4}", _exception.Message, + Environment.NewLine, details, "".PadLeft(10, '-'), + stackTrace); + + return detailedErrorMessage; + } + } + + private void DrawErrorMessage() + { + txtErrorMessage.Text = Exceptiontext; + } + + private void BtnCopyError_Click(object sender, EventArgs e) + { + Clipboard.SetText(Exceptiontext); + } + + private void BtnOK_Click(object sender, EventArgs e) + { + Close(); + } + + private void ChkboxShowDetails_CheckedChanged(object sender, EventArgs e) + { + DrawErrorMessage(); + } + + private void ChkboxShowStackTrace_CheckedChanged(object sender, EventArgs e) + { + DrawErrorMessage(); + } + } +} diff --git a/src/FlaUIRecorder/ExceptionForm.resx b/src/FlaUIRecorder/ExceptionForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/FlaUIRecorder/ExceptionForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/FlaUIRecorder/FlaUIRecorder.csproj b/src/FlaUIRecorder/FlaUIRecorder.csproj index d132095..b7af4b2 100644 --- a/src/FlaUIRecorder/FlaUIRecorder.csproj +++ b/src/FlaUIRecorder/FlaUIRecorder.csproj @@ -87,6 +87,13 @@ CommentForm.cs + + Form + + + ExceptionForm.cs + + @@ -116,6 +123,9 @@ CommentForm.cs + + ExceptionForm.cs + MainForm.cs diff --git a/src/FlaUIRecorder/Program.cs b/src/FlaUIRecorder/Program.cs index 4368b6c..5682904 100644 --- a/src/FlaUIRecorder/Program.cs +++ b/src/FlaUIRecorder/Program.cs @@ -1,22 +1,53 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Reflection; +using System.Threading; using System.Windows.Forms; namespace FlaUIRecorder { - static class Program + public static class Program { /// /// The main entry point for the application. /// [STAThread] - static void Main() + public static void Main() { + var assemblyTitle = Assembly.GetEntryAssembly().GetCustomAttribute(typeof(AssemblyTitleAttribute)) as AssemblyTitleAttribute; + Thread.CurrentThread.Name = assemblyTitle.Title; + + AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; + Application.ThreadException += ApplicationThreadException; + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + Application.DoEvents(); Application.Run(new MainForm()); } + + private static void ExitApplication() + { + Application.ThreadException -= ApplicationThreadException; + AppDomain.CurrentDomain.UnhandledException -= CurrentDomainUnhandledException; + + Application.Exit(); + } + + private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) + { + ShowExceptionDialog(e.Exception); + } + + private static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + ShowExceptionDialog(e.ExceptionObject as Exception); + } + private static void ShowExceptionDialog(Exception ex) + { + using (var exceptionForm = new ExceptionForm(ex)) + { + exceptionForm.ShowDialog(); + } + } } }