Skip to content

Commit

Permalink
Report bugs in a separate process
Browse files Browse the repository at this point in the history
- If an unhandled exception is throw on the main thread, show the error
within the app process. The error may or may not be fatal.
This code path is for the most part unchanged from the existing
behaviour.

- If an unhandled exception is thrown from a background thread it
will crash the app. Serialize and encode the error information as base64
string, and launch the bug reporter app before terminating the app.

- The bug report exception handling is updated to use SerializableException
type to accommodate both -in-app and out-of-proc exception reporting.
  • Loading branch information
RussKie committed Apr 19, 2021
1 parent 46dd4a4 commit c110895
Show file tree
Hide file tree
Showing 52 changed files with 998 additions and 162 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 63 additions & 13 deletions GitUI/NBugReports/BugReportForm.cs → BugReporter/BugReportForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

#nullable disable

using System;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using BugReporter.Properties;
using BugReporter.Serialization;
using GitCommands;
using GitExtUtils.GitUI;
using GitUI.NBugReports.Info;
using GitUI.NBugReports.Serialization;
using GitUI.Properties;
using GitUI;
using ResourceManager;
using Report = BugReporter.Info.Report;

namespace GitUI.NBugReports
namespace BugReporter
{
public partial class BugReportForm : GitExtensionsForm
public partial class BugReportForm : Form, ITranslate
{
private readonly TranslationString _title = new("Error Report");
private readonly TranslationString _submitGitHubMessage = new(@"Give as much as information as possible please to help the developers solve this issue. Otherwise, your issue ticket may be closed without any follow-up from the developers.
Expand Down Expand Up @@ -60,7 +64,12 @@ public BugReportForm()
warningLabel.MaximumSize = new Size(warningLabel.Width, 0);
warningLabel.AutoSize = true;

InitializeComplete();
AutoScaleMode = AppSettings.EnableAutoScale
? AutoScaleMode.Dpi
: AutoScaleMode.None;

this.AdjustForDpiScaling();
this.EnableRemoveWordHotkey();

toolTip.SetToolTip(btnCopy, _toolTipCopy.Text);
toolTip.SetToolTip(sendAndQuitButton, _toolTipSendQuit.Text);
Expand All @@ -70,9 +79,9 @@ public BugReportForm()
mainTabs.TabPages.Remove(mainTabs.TabPages["reportContentsTabPage"]);
}

public DialogResult ShowDialog(IWin32Window owner, Exception exception, string environmentInfo, bool canIgnore, bool showIgnore, bool focusDetails)
public DialogResult ShowDialog(IWin32Window owner, SerializableException exception, string environmentInfo, bool canIgnore, bool showIgnore, bool focusDetails)
{
_lastException = new SerializableException(exception);
_lastException = exception;
_lastReport = new Report(_lastException);
_environmentInfo = environmentInfo;

Expand Down Expand Up @@ -118,7 +127,7 @@ protected override void OnShown(EventArgs e)
descriptionTextBox.Focus();
}

private bool CheckContainsInfo(string input)
private static bool CheckContainsInfo(string input)
{
var text = Regex.Replace(input, @"\s*|\r|\n", string.Empty);
return !string.IsNullOrWhiteSpace(text);
Expand Down Expand Up @@ -146,16 +155,16 @@ private void SendAndQuitButton_Click(object sender, EventArgs e)
return;
}

string url = UrlBuilder.Build("https://github.com/gitextensions/gitextensions/issues/new", _lastException.OriginalException, _environmentInfo, descriptionTextBox.Text);
OsShellUtil.OpenUrlInDefaultBrowser(url);
string url = UrlBuilder.Build("https://github.com/gitextensions/gitextensions/issues/new", _lastException, _environmentInfo, descriptionTextBox.Text);
new Executable(url!).Start(useShellExecute: true);

DialogResult = DialogResult.Abort;
Close();
}

private void btnCopy_Click(object sender, EventArgs e)
{
var report = ErrorReportBodyBuilder.Build(_lastException.OriginalException, _environmentInfo, descriptionTextBox.Text);
var report = ErrorReportBodyBuilder.Build(_lastException, _environmentInfo, descriptionTextBox.Text);
if (string.IsNullOrWhiteSpace(report))
{
return;
Expand All @@ -172,6 +181,37 @@ private void IgnoreButton_Click(object sender, EventArgs e)
Close();
}

#region Translation

public virtual void AddTranslationItems(ITranslation translation)
{
TranslationUtils.AddTranslationItemsFromFields(Name, this, translation);
}

public virtual void TranslateItems(ITranslation translation)
{
TranslationUtils.TranslateItemsFromFields(Name, this, translation);
}

protected void TranslateItem(string itemName, object item)
{
var translation = Translator.GetTranslation(AppSettings.CurrentTranslation);

if (translation.Count == 0)
{
return;
}

var itemsToTranslate = new[] { (itemName, item) };

foreach (var pair in translation)
{
TranslationUtils.TranslateItemsFromList(Name, pair.Value, itemsToTranslate);
}
}

#endregion

internal TestAccessor GetTestAccessor()
=> new TestAccessor(this);

Expand All @@ -184,7 +224,17 @@ public TestAccessor(BugReportForm form)
_form = form;
}

public bool CheckContainsInfo(string input) => _form.CheckContainsInfo(input);
public TextBox ExceptionTextBox => _form.exceptionTextBox;
public TextBox ExceptionMessageTextBox => _form.exceptionMessageTextBox;
public TextBox TargetSiteTextBox => _form.targetSiteTextBox;
public ExceptionDetails ExceptionDetails => _form.exceptionDetails;

public TextBox ApplicationTextBox => _form.applicationTextBox;
public TextBox GitTextBox => _form.gitTextBox;
public TextBox DateTimeTextBox => _form.dateTimeTextBox;
public TextBox ClrTextBox => _form.clrTextBox;

public static bool CheckContainsInfo(string input) => BugReportForm.CheckContainsInfo(input);
}
}
}
50 changes: 50 additions & 0 deletions BugReporter/BugReporter.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<ApplicationIcon>Resources\git-extensions-logo.ico</ApplicationIcon>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs" Link="Properties\CommonAssemblyInfo.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GitExtUtils\GitExtUtils.csproj" />
<ProjectReference Include="..\ResourceManager\ResourceManager.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="GitInfo">
<Version>2.0.21</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Compile Update="ExceptionDetails.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="ExceptionDetailView.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
using System;
using System.Text;
using BugReporter.Serialization;
using GitExtensions;
using GitExtUtils;

namespace GitUI.NBugReports
namespace BugReporter
{
public interface IErrorReportMarkDownBodyBuilder
{
string Build(Exception exception, string environmentInfo, string additionalInfo);
string Build(SerializableException exception, string? environmentInfo, string? additionalInfo);
}

public sealed class ErrorReportMarkDownBodyBuilder : IErrorReportMarkDownBodyBuilder
{
public string Build(Exception exception, string environmentInfo, string additionalInfo)
public string Build(SerializableException exception, string? environmentInfo, string? additionalInfo)
{
if (exception is null)
{
Expand Down Expand Up @@ -45,7 +48,7 @@ public string Build(Exception exception, string environmentInfo, string addition
sb.AppendLine();
sb.AppendLine();

if (!string.IsNullOrWhiteSpace(additionalInfo))
if (!Strings.IsNullOrWhiteSpace(additionalInfo))
{
sb.AppendLine("## Additional information");
sb.AppendLine(additionalInfo.Trim());
Expand All @@ -57,7 +60,7 @@ public string Build(Exception exception, string environmentInfo, string addition
{
sb.AppendLine("## Environment");

if (!string.IsNullOrWhiteSpace(environmentInfo))
if (!Strings.IsNullOrWhiteSpace(environmentInfo))
{
sb.AppendLine(environmentInfo);
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

using System.Windows.Forms;

namespace GitUI.NBugReports
namespace BugReporter
{
internal partial class ExceptionDetailView : Form
{
Expand Down
File renamed without changes.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using GitUI.NBugReports.Serialization;
using BugReporter.Serialization;

namespace GitUI.NBugReports
namespace BugReporter
{
internal partial class ExceptionDetails : UserControl
{
Expand Down Expand Up @@ -157,5 +157,20 @@ private void FillInnerExceptionTree(SerializableException innerException, TreeNo
FillInnerExceptionTree(innerException.InnerException, innerNode.Nodes[0]);
}
}

internal TestAccessor GetTestAccessor()
=> new TestAccessor(this);

internal readonly struct TestAccessor
{
private readonly ExceptionDetails _form;

public TestAccessor(ExceptionDetails form)
{
_form = form;
}

public ListView ExceptionDetailsListView => _form.exceptionDetailsListView;
}
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// --------------------------------------------------------------------------------------------------------------------

using System;
using BugReporter.Serialization;

namespace GitUI.NBugReports
namespace BugReporter
{
public sealed class GitHubUrlBuilder
{
Expand All @@ -21,7 +22,7 @@ public GitHubUrlBuilder(IErrorReportMarkDownBodyBuilder errorReportMarkDownBodyB
/// Generates a URL to create a new issue on GitHub.
/// </summary>
/// <see href="https://help.github.com/en/articles/about-automation-for-issues-and-pull-requests-with-query-parameters"/>
public string Build(string url, Exception exception, string environmentInfo, string additionalInfo)
public string? Build(string url, SerializableException exception, string? environmentInfo, string? additionalInfo)
{
if (string.IsNullOrWhiteSpace(url) || exception is null)
{
Expand All @@ -48,4 +49,4 @@ public string Build(string url, Exception exception, string environmentInfo, str
return $"{validatedUri}{separator}title={Uri.EscapeDataString(subject)}&body={body}";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace GitUI.NBugReports.Info
namespace BugReporter.Info
{
public class AssemblyInfo
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace GitUI.NBugReports.Info
namespace BugReporter.Info
{
public class ConfigurationInfo
{
}
}
}
Loading

0 comments on commit c110895

Please sign in to comment.