#pragma warning disable IDE1006 // Naming Styles public static async Task Main(string[] args) { // Capture blazor bootstrapping errors using var sdk = SentrySdk.Init(o => { o.Dsn = "https://[email protected]/5428537"; o.Debug = true; }); try { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("#app"); builder.Logging.SetMinimumLevel(LogLevel.Debug); // Captures logError and higher as events builder.Logging.AddSentry(o => o.InitializeSdk = false); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); await builder.Build().RunAsync(); } catch (Exception e) { SentrySdk.CaptureException(e); await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)); throw; } }
static async Task Main( string?upload = null, string?check = null, string?path = null, string?symsorter = null, string?bundleId = null, string?batchType = null, bool dryrun = false, Uri?serverEndpoint = null) { var cancellation = new CancellationTokenSource(); var userAgent = "Console/" + typeof(Program).Assembly.GetName().Version; var args = new Args(upload, check, path, symsorter, bundleId, batchType, serverEndpoint, userAgent, dryrun, cancellation); Bootstrap(args); try { await Run(args); } catch (Exception e) { WriteLine(e); SentrySdk.CaptureException(e); } finally { await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)); } }
public static void WithErrorReporting(Action action) { var appInformationalVersion = TJAPlayer3.AppInformationalVersion; using (SentrySdk.Init(o => { o.Dsn = new Dsn("https://[email protected]/3365560"); o.Environment = GetEnvironment(appInformationalVersion); o.ShutdownTimeout = TimeSpan.FromSeconds(5); })) { try { Application.ThreadException += (sender, args) => { ReportError(args.Exception); }; TaskScheduler.UnobservedTaskException += (sender, args) => { ReportError(args.Exception); }; action(); } catch (Exception e) { ReportError(e); SentrySdk.FlushAsync(TimeSpan.FromSeconds(5)); NotifyUserOfError(e); } } }
static async Task Main( string?upload = null, string?check = null, string?path = null, string?symsorter = null, string?bundleId = null, string?batchType = null, bool dryrun = false, Uri?serverEndpoint = null) { var cancellation = new CancellationTokenSource(); var userAgent = "Console/" + typeof(Program).Assembly.GetName().Version; var args = new Args(upload, check, path, symsorter, bundleId, batchType, serverEndpoint, userAgent, dryrun, cancellation); Bootstrap(args); try { using var host = Startup.Init(s => { if (args.ServerEndpoint != null) { s.AddOptions() .PostConfigure <SymbolClientOptions>(o => { o.UserAgent = args.UserAgent; o.BaseAddress = args.ServerEndpoint; }); } s.AddHttpClient <ISymbolClient, SymbolClient>() .AddPolicyHandler((s, r) => HttpPolicyExtensions.HandleTransientHttpError() .SentryPolicy(s)); s.AddSingleton(Metrics); s.AddSingleton <ConsoleUploader>(); s.AddSingleton <Symsorter>(); s.AddOptions <SymsorterOptions>() .Configure <IConfiguration>((o, f) => f.Bind("Symsorter", o)); }); await Run(host, args); } catch (Exception e) { WriteLine(e); // if rethrown, System.CommandLine.DragonFruit will capture handle instead of piping to AppDomain e.Data[Mechanism.HandledKey] = false; e.Data[Mechanism.MechanismKey] = "Main.UnhandledException"; SentrySdk.CaptureException(e); } finally { await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)); } }
public void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs args) { SentrySdk.ConfigureScope(scope => scope.SetTag("Handled", "False") ); SentrySdk.CaptureException((Exception)args.ExceptionObject); SentrySdk.FlushAsync(new TimeSpan(0, 1, 0)).Wait(); // 1 minute to send or to make an offline backup }
private async Task CallThrow() { try { ThrowEx(); } catch (Exception e) { SentrySdk.CaptureException(e); await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)); } }
/// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); SentrySdk.AddBreadcrumb("Suspending app."); // TODO: Does this block the UI thread? SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)).Wait(); //TODO: Save application state and stop any background activity deferral.Complete(); }
internal NativeExceptionHandler() { AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => { var exceptionEvent = new SentryEvent(args.Exception); exceptionEvent.SentryExceptions.First().Mechanism = new Mechanism() { Handled = false, Type = "AndroidEnvironment_UnhandledExceptionRaiser" }; SentrySdk.CaptureEvent(exceptionEvent); SentrySdk.FlushAsync(TimeSpan.FromSeconds(10)).Wait(); }; }
private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) { if (Debugger.IsAttached) { return; } if (e.IsTerminating) { Exception ex = (Exception)e.ExceptionObject; Exception inner = ex; while (ex.InnerException is not null) { if (IgnoredExceptions.Contains(inner.GetType())) { return; } inner = ex.InnerException; } // If this exception is not ignored, send it to sentry if (!IgnoredExceptions.Contains(inner.GetType())) { _sentry.Dispose(); using (InitSentry()) { SentrySdk.WithScope(scope => { string filename = CollectAll(); scope.AddAttachment(filename); SentrySdk.CaptureException(ex); File.Delete(filename); }); SentrySdk.FlushAsync(TimeSpan.FromSeconds(10)).GetAwaiter().GetResult(); } MessageBox.Show($"Something went wrong and the application needs to exit.\n{inner.Message}\nInformation about this error (installed mods, error details) were sent to the developer.", "Fatal error", MessageBoxButton.OK, MessageBoxImage.Error); // Otherwise log it to disk. } else { WriteExceptionToDisk(ex); MessageBox.Show($"Something went wrong and the application needs to exit.\n{inner.Message}\nInformation about this error was saved to the application folder and is probably an issue local to your computer.", "Fatal error", MessageBoxButton.OK, MessageBoxImage.Error); } } }
public void Handle(Null _) { _application.UnhandledException += (_, args) => { using (SentrySdk.PushScope()) { SentrySdk.ConfigureScope(s => s.SetTag("UnhandledException", "true")); SentrySdk.CaptureException(args.Exception); if (!args.Handled) // Not handled yet { // App might crash so make sure we flush this event. SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)).Wait(); } } }; }
private static void Game_UnhandledException(object sender, Stride.Games.GameUnhandledExceptionEventArgs ex) { // Is this needed? This code already exists inside Sentry's SDK on AppDomain.UnhandledException if (ex.ExceptionObject is Exception e) { e.Data["Sentry:Handled"] = false; e.Data["Sentry:Mechanism"] = "Game.UnhandledException"; SentrySdk.CaptureException(e); SentrySdk.FlushAsync(TimeSpan.FromSeconds(10)).Wait(); } if (ex.IsTerminating) { SentrySdk.Close(); // Flush events and close. } }
static async Task Main(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Sentry(o => { o.InitializeSdk = true; o.MaxQueueItems = 10; o.MinimumBreadcrumbLevel = Serilog.Events.LogEventLevel.Debug; o.Dsn = new Dsn("<sentryDSN>"); }) .WriteTo.Console() .WriteTo.File("app.log", fileSizeLimitBytes: 20000000, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day) .CreateLogger(); //setup our DI var serviceProvider = new ServiceCollection() .AddSingleton <ILoggerFactory>(sc => { var factory = new SerilogLoggerFactory(null, true); return(factory); }) .AddLogging() .AddDIDemoLib() .BuildServiceProvider(); var logger = serviceProvider.GetService <ILoggerFactory>() .CreateLogger <Program>(); logger.LogDebug("Starting application"); var client = serviceProvider.GetService <IApiClient>(); client.OnException += OnException; client.InvokExceptionHandler(); client.FooMethod(); logger.LogDebug("The End"); //Flush all the logs in the queue to Serilog Log.CloseAndFlush(); //FLush All logs in the queue to sentry await SentrySdk.FlushAsync(TimeSpan.FromMinutes(1)); }
public async Task Import(IJobCancellationToken token) { using var _ = _hub.PushScope(); var transaction = _hub.StartTransaction("import-catalog", "catalog.import"); _hub.ConfigureScope(s => s.Transaction = transaction); var logger = _loggerFactory.CreateLogger <NuGetCatalogImporter>(); logger.LogInformation("Starting importing catalog."); try { var httpClient = _httpClientFactory.CreateClient("nuget"); var catalogClient = new CatalogClient(httpClient, _loggerFactory.CreateLogger <CatalogClient>()); var settings = new CatalogProcessorSettings { DefaultMinCommitTimestamp = DateTimeOffset.MinValue, // Read everything ExcludeRedundantLeaves = false, }; var catalogProcessor = new CatalogProcessor( _cursorStore, catalogClient, _catalogLeafProcessor, settings, _loggerFactory.CreateLogger <CatalogProcessor>()); await catalogProcessor.ProcessAsync(token.ShutdownToken); logger.LogInformation("Finished importing catalog."); transaction.Finish(SpanStatus.Ok); } catch (Exception e) { transaction.Finish(e); SentrySdk.CaptureException(e); throw; } finally { await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)); } }
public Task StartUpload(string friendlyName, CancellationToken token) => Task.Run(async() => { var paths = new[] { "/system/lib", "/system/lib64", "/system/", "/vendor/lib" }; _logger.LogInformation("Using friendly name: {friendlyName} and paths: {paths}", friendlyName, paths); try { await _client.UploadAllPathsAsync(friendlyName, BatchType.Android, paths, token); } catch (OperationCanceledException) { } catch (Exception e) { _logger.LogError(e, "Failed uploading {friendlyName} paths: {paths}", friendlyName, paths); // Make sure event is flushed and rethrow await SentrySdk.FlushAsync(TimeSpan.FromSeconds(3)); throw; } }, token);
private static async Task Main() { // When the SDK is disabled, no callback is executed: await SentrySdk.ConfigureScopeAsync(async scope => { // Never executed: // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("Key", "Value"); }); // Enable the SDK using (SentrySdk.Init(o => { // Send stack trace for events that were not created from an exception // e.g: CaptureMessage, log.LogDebug, log.LogInformation ... o.AttachStacktrace = true; // Sentry won't consider code from namespace LibraryX.* as part of the app code and will hide it from the stacktrace by default // To see the lines from non `AppCode`, select `Full`. Will include non App code like System.*, Microsoft.* and LibraryX.* o.AddInAppExclude("LibraryX."); // Before excluding all prefixed 'LibraryX.', any stack trace from a type namespaced 'LibraryX.Core' will be considered InApp. o.AddInAppInclude("LibraryX.Core"); // Send personal identifiable information like the username logged on to the computer and machine name o.SendDefaultPii = true; // To enable event sampling, uncomment: // o.SampleRate = 0.5f; // Randomly drop (don't send to Sentry) half of events // Modifications to event before it goes out. Could replace the event altogether o.BeforeSend = @event => { // Drop an event altogether: if (@event.Tags.ContainsKey("SomeTag")) { return(null); } return(@event); }; // Allows inspecting and modifying, returning a new or simply rejecting (returning null) o.BeforeBreadcrumb = crumb => { // Don't add breadcrumbs with message containing: if (crumb.Message?.Contains("bad breadcrumb") == true) { return(null); } return(crumb); }; // Ignore exception by its type: o.AddExceptionFilterForType <XsltCompileException>(); // Configure the background worker which sends events to sentry: // Wait up to 5 seconds before shutdown while there are events to send. o.ShutdownTimeout = TimeSpan.FromSeconds(5); // Enable SDK logging with Debug level o.Debug = true; // To change the verbosity, use: // o.DiagnosticLevel = SentryLevel.Info; // To use a custom logger: // o.DiagnosticLogger = ... // Using a proxy: o.HttpProxy = null; //new WebProxy("https://*****:*****@user{timestamp}.com"; SentrySdk.CaptureUserFeedback(new UserFeedback(eventId, user, email, "this is a sample user feedback")); var error = new Exception("Attempting to send this multiple times"); // Only the first capture will be sent to Sentry for (var i = 0; i < 3; i++) { // The SDK is able to detect duplicate events: // This is useful, for example, when multiple loggers log the same exception. Or exception is re-thrown and recaptured. SentrySdk.CaptureException(error); } var count = 10; for (var i = 0; i < count; i++) { const string msg = "{0} of {1} items we'll wait to flush to Sentry!"; SentrySdk.CaptureEvent(new SentryEvent { Message = new SentryMessage { Message = msg, Formatted = string.Format(msg, i, count) }, Level = SentryLevel.Debug }); } // Console output will show queue being flushed. Task completes then and timeout is never reached (you don't need to wait a day :) await SentrySdk.FlushAsync(TimeSpan.FromDays(1)); // ------------------------- // A custom made client, that could be registered with DI, // would get disposed by the container on app shutdown var evt = new SentryEvent(); evt.Message = "Starting new client"; evt.AddBreadcrumb("Breadcrumb directly to the event"); evt.User.Username = "******"; // Group all events with the following fingerprint: evt.SetFingerprint(new [] { "NewClientDebug" }); evt.Level = SentryLevel.Debug; SentrySdk.CaptureEvent(evt); // Using a different DSN: using (var adminClient = new SentryClient(new SentryOptions { Dsn = AdminDsn })) { // Make believe web framework middleware var middleware = new AdminPartMiddleware(adminClient, null); var request = new { Path = "/admin" }; // made up request middleware.Invoke(request); } // Dispose the client which flushes any queued events SentrySdk.CaptureException( new Exception("Error outside of the admin section: Goes to the default DSN")); } // On Dispose: SDK closed, events queued are flushed/sent to Sentry }
public static void WithErrorReporting(Action action) { using (SentrySdk.Init(o => { try { o.Dsn = new Dsn("https://[email protected]/3365560"); } catch { // ignored } try { o.Environment = GetEnvironment(TJAPlayer3.AppInformationalVersion); } catch { // ignored } try { o.ServerName = ToSha256InBase64(Environment.MachineName); } catch { // ignored } try { o.ShutdownTimeout = TimeSpan.FromSeconds(5); } catch { // ignored } })) { try { try { SentrySdk.ConfigureScope(scope => { scope.User.Username = ToSha256InBase64(Environment.UserName); }); } catch { // ignored } Application.ThreadException += (sender, args) => { ReportError(args.Exception); }; TaskScheduler.UnobservedTaskException += (sender, args) => { ReportError(args.Exception); }; action(); } catch (Exception e) { ReportError(e); var task = SentrySdk.FlushAsync(TimeSpan.FromSeconds(5)); try { NotifyUserOfError(e); } catch { // ignored } task.Wait(); } } }