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

Make Scope data global on desktop and mobile #628

Closed
bruno-garcia opened this issue Nov 29, 2020 · 5 comments · Fixed by #1124
Closed

Make Scope data global on desktop and mobile #628

bruno-garcia opened this issue Nov 29, 2020 · 5 comments · Fixed by #1124
Labels

Comments

@bruno-garcia
Copy link
Member

bruno-garcia commented Nov 29, 2020

This came up a few times, more recently on SO:

https://stackoverflow.com/questions/65066020/c-xamarin-forms-and-sentrysdk-context-info-not-making-it-to-sentry-errors

Currently the Hub is stored in a AsyncLocal field so data forks on new asynchronous flows.
This causes problems for Desktop and Mobile apps that want to push work to a back ground thread but would like that data available in case of an error anywhere.

This is how the Android and iOS SDKs of Sentry work, with a static global Hub.

An attempt to simulate that happened in this PR #448 but we the general approach needs to be discussed.

Resolves: #221

More context: https://forum.sentry.io/t/accessing-and-ensuring-global-shared-scope-in-net/11709/2

@jairbubbles
Copy link
Contributor

jairbubbles commented May 17, 2021

Hello @bruno-garcia,

I was hit by the same issue and I must say it took me time to figure out what was going on (and get the source code). It's really counter-intuitive.

I wanted to track events and I was receiving them through different callbacks on different threads. As a workaround I ended up creating a specific scope that I use as a container for my events:

private readonly BaseScope _breadCrumbsScope = new Scope(null);

When I need to report an exception I fill everything I need just before sending it so I'm sure it's on the good scope:

SentrySdk.ConfigureScope(scope =>
{
  foreach (var breadCrumb in _breadCrumbsScope.Breadcrumbs)
  {
    scope.AddBreadcrumb(message: breadCrumb.Message, category: breadCrumb.Category, type: breadCrumb.Type, data: (Dictionary<string, string>)breadCrumb.Data, level: breadCrumb.Level);
   }
});

// Fill other things like user info and meta data

SentrySdk.CaptureException(exception);

As a side note, I do not use the embedded exception handling.

@bruno-garcia
Copy link
Member Author

Thanks for sharing your work around @jairbubbles and sorry you hit this issue and took time to trace down.
This is a serious issue in usability from Desktop and Mobile users and really needs addressing. @rhcarvalho while working on tracing API became aware of the single/global state vs local state issues different SDKs have and we're discussing new APIs we can introduce to support both modes. A state change that that should be local to the local scope or globally visible to the whole process.

We'll hopefully get to this soon with a solution.

@bruno-garcia
Copy link
Member Author

Customers also have the need to change data globally outside desktop apps. When they want to add such tags for data that's resolved only later in the program's executing. After a call to the backend for example that runs parallel to the process bootstrapping.

@jairbubbles
Copy link
Contributor

In my case I wouldn't mind managing the global scope on my own, exposing static functions is nice but can be misleading.

@bruno-garcia
Copy link
Member Author

We solved "Global Mode" on version 3.8.1.

It makes it so that any call to SentrySdk.SetTag or AddBreadcrumb or anything else that you do through SentrySdk.ConfigureScope mutates a single, static Scope object that affects all threads of the app. This is useful for Desktop and Mobile apps when you have a single user session and you add context to Sentry anywhere in the app and want that to be included if it crashes in any other thread.

You can opt-in to this mode through:

options.IsGlobalModeEnabled = true

To clarify: This options doesn't make sense in any sort of web server where each individual request takes a separate scope (You want each SetTag("url", ...) to take a different request URL, headers etc). Nothing needs to be done for server apps, it continues to work as it did in the past.

We plan to ship Sentry.Wpf and Sentry.WinForms in the future that would already flip IsGlobalModeEnabled = true for you. Until then we'll add to the docs that you can do that if you prefer to have a single mutable state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants