Skip to content

Commit

Permalink
Add Sentry.io Integration (Valkirie#309)
Browse files Browse the repository at this point in the history
* add sentry integration

* Update App.xaml.cs

* update sentry integration

remove bat file, put the command inside csproj
add SentryConfig.cs to git
enable Sentry debug only on debug build

* update prebuild and postbuild command

* code style

* Use default %localappdata%\HandheldCompanion folder

* Push all crash Exception(s) to Sentry

---------

Co-authored-by: Lesueur Benjamin <[email protected]>
  • Loading branch information
joshuatam and Valkirie authored Jun 10, 2024
1 parent 410759d commit ac56512
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ install/
*.user
*Backup.csproj
*tmp.csproj
.idea/
.idea/
85 changes: 77 additions & 8 deletions HandheldCompanion/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Sentry;
using Sentry.Profiling;
using static HandheldCompanion.WinAPI;

namespace HandheldCompanion;
Expand All @@ -24,6 +27,7 @@ public partial class App : Application
/// </summary>
public App()
{
InitializeSentry();
InitializeComponent();
}

Expand Down Expand Up @@ -108,30 +112,95 @@ protected override void OnStartup(StartupEventArgs args)
currentDomain.UnhandledException += CurrentDomain_UnhandledException;
// Handler for exceptions in threads behind forms.
System.Windows.Forms.Application.ThreadException += Application_ThreadException;
// Handler for exceptions in dispatcher.
DispatcherUnhandledException += App_DispatcherUnhandledException;

MainWindow = new MainWindow(fileVersionInfo, CurrentAssembly);
MainWindow.Show();
}

private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
var ex = default(Exception);
ex = (Exception)e.Exception;
Exception ex = (Exception)e.Exception;

// send to sentry
if (SentrySdk.IsEnabled)
SentrySdk.CaptureException(ex);

if (ex.InnerException != null)
{
LogManager.LogCritical(ex.InnerException.Message + "\t" + ex.InnerException.StackTrace);
}

LogManager.LogCritical(ex.Message + "\t" + ex.StackTrace);
}

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = default(Exception);
ex = (Exception)e.ExceptionObject;
Exception ex = (Exception)e.ExceptionObject;

// send to sentry
if (SentrySdk.IsEnabled)
SentrySdk.CaptureException(ex);

if (ex.InnerException != null)
{
LogManager.LogCritical(ex.InnerException.Message + "\t" + ex.InnerException.StackTrace);
}

LogManager.LogCritical(ex.Message + "\t" + ex.StackTrace);
}

private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.Exception;

// send to sentry
if (SentrySdk.IsEnabled)
SentrySdk.CaptureException(ex);

if (ex.InnerException != null)
LogManager.LogCritical(ex.InnerException.Message + "\t" + ex.InnerException.StackTrace);

LogManager.LogCritical(ex.Message + "\t" + ex.StackTrace);

// If you want to avoid the application from crashing:
e.Handled = true;
}

private void InitializeSentry()
{
string url = SentryConfig.DSN_URL;

if (!string.IsNullOrEmpty(url))
{
SentrySdk.Init(options =>
{
// Tells which project in Sentry to send events to:
options.Dsn = url;

#if DEBUG
// When configuring for the first time, to see what the SDK is doing:
options.Debug = true;
#else
options.Debug = false;
#endif

// Enable Global Mode since this is a client app
options.IsGlobalModeEnabled = true;

// Set traces_sample_rate to 1.0 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.TracesSampleRate = 1.0;

// Sample rate for profiling, applied on top of othe TracesSampleRate,
// e.g. 0.2 means we want to profile 20 % of the captured transactions.
// We recommend adjusting this value in production.
options.ProfilesSampleRate = 1.0;

// Requires NuGet package: Sentry.Profiling
// Note: By default, the profiler is initialized asynchronously. This can be tuned by passing a desired initialization timeout to the constructor.
options.AddIntegration(new ProfilingIntegration(
// During startup, wait up to 500ms to profile the app startup code. This could make launching the app a bit slower so comment it out if your prefer profiling to start asynchronously
TimeSpan.FromMilliseconds(500)
));
});
}
}
}
14 changes: 13 additions & 1 deletion HandheldCompanion/HandheldCompanion.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>
<OutputType>WinExe</OutputType>
Expand All @@ -16,6 +16,7 @@
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>AnyCPU;x64;x86</Platforms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
Expand Down Expand Up @@ -51,6 +52,7 @@
<ContainsDesignTimeResources>True</ContainsDesignTimeResources>
<SubType>Designer</SubType>
</None>
<None Include="SentryConfig.cs" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -171,6 +173,8 @@
<PackageReference Include="PInvoke.Kernel32" Version="0.7.124" />
<PackageReference Include="PixiEditor.ColorPicker" Version="3.3.1" />
<PackageReference Include="PrecisionTimer.NET" Version="2.2.5.3" />
<PackageReference Include="Sentry" Version="4.7.0" />
<PackageReference Include="Sentry.Profiling" Version="4.7.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.1" />
Expand Down Expand Up @@ -2351,4 +2355,12 @@
</Page>
</ItemGroup>

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="if exist &quot;%25LocalAppData%25\HandheldCompanion\SentryConfig.cs&quot; (&#xA; copy &quot;.\SentryConfig.cs&quot; &quot;.\SentryConfig.cs.bak&quot;&#xA; copy &quot;%25LocalAppData%25\HandheldCompanion\SentryConfig.cs&quot; &quot;.\SentryConfig.cs&quot;&#xA;)" />
</Target>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if exist &quot;.\SentryConfig.cs.bak&quot; (&#xA; copy &quot;.\SentryConfig.cs.bak&quot; &quot;.\SentryConfig.cs&quot;&#xA; del &quot;.\SentryConfig.cs.bak&quot;&#xA;)" />
</Target>

</Project>
7 changes: 7 additions & 0 deletions HandheldCompanion/SentryConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HandheldCompanion;

public static class SentryConfig
{
// Register at Sentry.io and paste the DSN url here
public static string DSN_URL = "";
}

0 comments on commit ac56512

Please sign in to comment.