diff --git a/samples/Sentry.Samples.Wpf/App.xaml b/samples/Sentry.Samples.Wpf/App.xaml new file mode 100644 index 0000000000..9577f99adf --- /dev/null +++ b/samples/Sentry.Samples.Wpf/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/samples/Sentry.Samples.Wpf/App.xaml.cs b/samples/Sentry.Samples.Wpf/App.xaml.cs new file mode 100644 index 0000000000..73a0acf78a --- /dev/null +++ b/samples/Sentry.Samples.Wpf/App.xaml.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Navigation; +using Sentry.Protocol; + +namespace Sentry.Samples.Wpf +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public App() + { + // TODO: Should be part of Sentry.Wpf and hook automatically + DispatcherUnhandledException += (sender, e) => + { + if (e.Exception is Exception ex) + { + ex.Data[Mechanism.HandledKey] = e.Handled; + ex.Data[Mechanism.MechanismKey] = "App.DispatcherUnhandledException"; + _ = SentrySdk.CaptureException(ex); + } + + if (!e.Handled) + { + // Unhandled will crash the app so flush the queue: + SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)).GetAwaiter().GetResult(); + } + }; + + SentrySdk.Init(o => + { + o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537"; + // TODO: Should print to VS debug window (similar to Sentry for ASP.NET) + o.Debug = true; + // TODO: Doesn't support multiple instances of the process on the same directory yet + o.CacheDirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + // For testing, set to 100% transactions for performance monitoring. + o.TracesSampleRate = 1.0; + }); + } + + protected override void OnStartup(StartupEventArgs e) + { + SentrySdk.AddBreadcrumb("OnStartup", "app.lifecycle"); + SentrySdk.ConfigureScope(s => s.Transaction = SentrySdk.StartTransaction("Startup", "app.start")); + base.OnStartup(e); + } + + protected override void OnNavigating(NavigatingCancelEventArgs e) + { + SentrySdk.AddBreadcrumb("NavigatingCancelEventArgs", + "navigation", + data: new Dictionary + { + {"url", e.Uri.ToString()} + }); + base.OnNavigating(e); + } + + protected override void OnFragmentNavigation(FragmentNavigationEventArgs e) + { + SentrySdk.AddBreadcrumb("OnFragmentNavigation", + "navigation", + data: new Dictionary + { + {"fragment", e.Fragment}, + {"handled", e.Handled.ToString()} + }); + base.OnFragmentNavigation(e); + } + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + SentrySdk.Close(); + } + } +} diff --git a/samples/Sentry.Samples.Wpf/AssemblyInfo.cs b/samples/Sentry.Samples.Wpf/AssemblyInfo.cs new file mode 100644 index 0000000000..8b5504ecfb --- /dev/null +++ b/samples/Sentry.Samples.Wpf/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/samples/Sentry.Samples.Wpf/MainWindow.xaml b/samples/Sentry.Samples.Wpf/MainWindow.xaml new file mode 100644 index 0000000000..85722fdaa6 --- /dev/null +++ b/samples/Sentry.Samples.Wpf/MainWindow.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs b/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs new file mode 100644 index 0000000000..b7c2f9902b --- /dev/null +++ b/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs @@ -0,0 +1,32 @@ +using System; +using System.Windows; + +namespace Sentry.Samples.Wpf +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() => InitializeComponent(); + + private ISpan _initSpan; + + public override void BeginInit() + { + _initSpan = SentrySdk.GetSpan()?.StartChild("BeginInit"); + base.BeginInit(); + } + + public override void EndInit() + { + base.EndInit(); + _initSpan?.Finish(); + // Is this the API to close the current transaction bound to the scope? Maybe we need to revisit this.. + SentrySdk.ConfigureScope(s => s.Transaction?.Finish()); + } + + private void ButtonBase_OnClick(object sender, RoutedEventArgs e) + => throw new InvalidOperationException("This button shall not be pressed!"); + } +} diff --git a/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj b/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj new file mode 100644 index 0000000000..a6e5d7da84 --- /dev/null +++ b/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj @@ -0,0 +1,13 @@ + + + + WinExe + net6.0-windows + true + + + + + + +