Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unobserved exception handling #125

Merged
merged 6 commits into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ Changelog

### Bug fixes

* Handle any exceptions raised when reading files for code segments
* Handle any exceptions raised when reading files for code segments.
| [twometresteve](https://github.com/twometresteve)
| [#123](https://github.com/bugsnag/bugsnag-dotnet/pull/123)

* Account for process termination behavior when handling UnobservedTaskExceptions.
| [twometresteve](https://github.com/twometresteve)
| [#125](https://github.com/bugsnag/bugsnag-dotnet/pull/125)

## 2.2.0 (2018-07-19)

### Enhancements
Expand Down
4 changes: 3 additions & 1 deletion src/Bugsnag/Bugsnag.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Bugsnag</PackageId>
<Title>Bugsnag .NET Notifier</Title>
Expand All @@ -19,6 +19,8 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.3.0" />
Expand Down
24 changes: 23 additions & 1 deletion src/Bugsnag/UnhandledException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ class UnhandledException

private readonly object _currentClientLock = new object();
private IClient _currentClient;
private bool _unobservedTerminates;

private UnhandledException()
{
_unobservedTerminates = DetermineUnobservedTerminates();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
Expand Down Expand Up @@ -46,14 +48,34 @@ public void ConfigureClient(IClient client, IConfiguration configuration)
}
}

/// <summary>
/// Determines if an UnobservedTaskException leads to the process terminating, based on the target
/// framework and (when applicable) configuration.
/// </summary>
/// <returns></returns>
private bool DetermineUnobservedTerminates()
{
#if NET35 || NET40
return true;
#elif NET45
System.Xml.Linq.XElement configFile = System.Xml.Linq.XElement.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var configValue = configFile?.Element("runtime")?.Element("ThrowUnobservedTaskExceptions")?.Attribute("enabled")?.Value;
bool value;
var success = bool.TryParse(configValue, out value);
return success && value;
#else //NETSTANDARD1_3 || NETSTANDARD2_0
return false;
#endif
}

private void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
HandleEvent(null, true);
}

private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
HandleEvent(e.Exception as Exception, !e.Observed);
HandleEvent(e.Exception as Exception, _unobservedTerminates && !e.Observed);
}

[HandleProcessCorruptedStateExceptions]
Expand Down