From 28e9845bbaeac21601a0d99762e11b87606c19a1 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 12:02:27 +1300 Subject: [PATCH 1/8] feat: User.Id can now be overriden (set to null) in Global mode Resolves #4172 - #4172 --- .../GlobalRootScopeIntegration.cs | 14 ++ src/Sentry/Internal/Enricher.cs | 7 +- src/Sentry/SentryOptions.cs | 7 + .../GlobalRootScopeIntegrationTests.cs | 145 ++++++++++++++++++ ...y_registered.DotNet9_0.DotNet.verified.txt | 18 +++ 5 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/Sentry/Integrations/GlobalRootScopeIntegration.cs create mode 100644 test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs diff --git a/src/Sentry/Integrations/GlobalRootScopeIntegration.cs b/src/Sentry/Integrations/GlobalRootScopeIntegration.cs new file mode 100644 index 0000000000..0a5a47c77f --- /dev/null +++ b/src/Sentry/Integrations/GlobalRootScopeIntegration.cs @@ -0,0 +1,14 @@ +namespace Sentry.Integrations; + +internal class GlobalRootScopeIntegration : ISdkIntegration +{ + public void Register(IHub hub, SentryOptions options) + { + if (!options.IsGlobalModeEnabled) + { + return; + } + + hub.ConfigureScope(scope => scope.User.Id ??= options.InstallationId); + } +} diff --git a/src/Sentry/Internal/Enricher.cs b/src/Sentry/Internal/Enricher.cs index 3d3629934a..269de8fcfa 100644 --- a/src/Sentry/Internal/Enricher.cs +++ b/src/Sentry/Internal/Enricher.cs @@ -92,7 +92,12 @@ public void Apply(IEventLike eventLike) eventLike.User.IpAddress ??= DefaultIpAddress; } - eventLike.User.Id ??= _options.InstallationId; + // Set by the GlobalRootScopeIntegration In global mode so that it can be overridden by the user. + // In non-global mode (e.g. ASP.NET Core) the enricher sets it here as a fallback. + if (!_options.IsGlobalModeEnabled) + { + eventLike.User.Id ??= _options.InstallationId; + } //Apply App startup and Boot time eventLike.Contexts.App.StartTime ??= ProcessInfo.Instance?.StartupTime; diff --git a/src/Sentry/SentryOptions.cs b/src/Sentry/SentryOptions.cs index 25a6eb3183..070728089a 100644 --- a/src/Sentry/SentryOptions.cs +++ b/src/Sentry/SentryOptions.cs @@ -220,6 +220,11 @@ internal IEnumerable Integrations } #endif + if ((_defaultIntegrations & DefaultIntegrations.GlobalRootScopeIntegration) != 0) + { + yield return new GlobalRootScopeIntegration(); + } + foreach (var integration in _integrations) { yield return integration; @@ -1362,6 +1367,7 @@ public SentryOptions() #if NET8_0_OR_GREATER | DefaultIntegrations.SystemDiagnosticsMetricsIntegration #endif + | DefaultIntegrations.GlobalRootScopeIntegration ; #if ANDROID @@ -1829,6 +1835,7 @@ internal enum DefaultIntegrations #if NET8_0_OR_GREATER SystemDiagnosticsMetricsIntegration = 1 << 7, #endif + GlobalRootScopeIntegration = 1 << 8, } internal void SetupLogging() diff --git a/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs b/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs new file mode 100644 index 0000000000..45efb94980 --- /dev/null +++ b/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs @@ -0,0 +1,145 @@ +using Sentry.Integrations; + +namespace Sentry.Tests.Integrations; + +public class GlobalRootScopeIntegrationTests +{ + [Fact] + public void Register_GlobalModeEnabled_SetsInstallationIdOnRootScope() + { + // Arrange + var options = new SentryOptions + { + Dsn = ValidDsn, + IsGlobalModeEnabled = true, + AutoSessionTracking = false + }; + + var hub = Substitute.For(); + var integration = new GlobalRootScopeIntegration(); + + // Act + integration.Register(hub, options); + + // Assert + hub.Received(1).ConfigureScope(Arg.Any>()); + } + + [Fact] + public void Register_GlobalModeDisabled_DoesNotConfigureScope() + { + // Arrange + var options = new SentryOptions + { + Dsn = ValidDsn, + IsGlobalModeEnabled = false, + AutoSessionTracking = false + }; + + var hub = Substitute.For(); + var integration = new GlobalRootScopeIntegration(); + + // Act + integration.Register(hub, options); + + // Assert + hub.DidNotReceive().ConfigureScope(Arg.Any>()); + } + + [Fact] + public void Register_GlobalModeEnabled_SetsUserIdFromInstallationId() + { + // Arrange + var options = new SentryOptions + { + Dsn = ValidDsn, + IsGlobalModeEnabled = true, + AutoSessionTracking = false + }; + + // Capture the action passed to ConfigureScope + Action capturedAction = null; + var hub = Substitute.For(); + hub.When(h => h.ConfigureScope(Arg.Any>())) + .Do(call => capturedAction = call.Arg>()); + + var integration = new GlobalRootScopeIntegration(); + integration.Register(hub, options); + + // Apply the captured action to a real scope + var scope = new Scope(options); + + capturedAction.Should().NotBeNull(); + capturedAction(scope); + + // The scope's User.Id should be set to the InstallationId + scope.User.Id.Should().Be(options.InstallationId); + } + + [Fact] + public void Register_GlobalModeEnabled_DoesNotOverwriteExistingUserId() + { + // Arrange + var options = new SentryOptions + { + Dsn = ValidDsn, + IsGlobalModeEnabled = true, + AutoSessionTracking = false + }; + + // Capture the action passed to ConfigureScope + Action capturedAction = null; + var hub = Substitute.For(); + hub.When(h => h.ConfigureScope(Arg.Any>())) + .Do(call => capturedAction = call.Arg>()); + + var integration = new GlobalRootScopeIntegration(); + integration.Register(hub, options); + + // Apply the captured action to a scope that already has a User.Id + var scope = new Scope(options); + const string existingUserId = "my-custom-user-id"; + scope.User.Id = existingUserId; + + capturedAction.Should().NotBeNull(); + capturedAction(scope); + + // The existing User.Id should not be overwritten + scope.User.Id.Should().Be(existingUserId); + } + + [Fact] + public void Enricher_GlobalModeEnabled_DoesNotSetInstallationId() + { + // Verify the enricher no longer sets User.Id when global mode is enabled, + // ensuring users can clear the User.Id set by GlobalRootScopeIntegration. + var options = new SentryOptions { IsGlobalModeEnabled = true }; + var enricher = new Sentry.Internal.Enricher(options); + + var eventLike = Substitute.For(); + eventLike.Sdk.Returns(new SdkVersion()); + eventLike.User = new SentryUser(); + eventLike.Contexts = new SentryContexts(); + + enricher.Apply(eventLike); + + eventLike.User.Id.Should().BeNull(); + } + + [Fact] + public void Enricher_GlobalModeDisabled_SetsInstallationIdAsFallback() + { + // Verify the enricher still sets User.Id when global mode is disabled (e.g. ASP.NET Core). + var options = new SentryOptions { IsGlobalModeEnabled = false }; + var enricher = new Sentry.Internal.Enricher(options); + + var eventLike = Substitute.For(); + eventLike.Sdk.Returns(new SdkVersion()); + eventLike.User = new SentryUser(); + eventLike.Contexts = new SentryContexts(); + + enricher.Apply(eventLike); + + eventLike.User.Id.Should().Be(options.InstallationId); + } +} diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt index f477fddad0..113305919d 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt @@ -37,5 +37,23 @@ Args: [ SentryDiagnosticListenerIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file From 1b15d0f03dba84b250f4bcd14e17cca6211098df Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 12:14:48 +1300 Subject: [PATCH 2/8] additional core verify tests --- src/Sentry/Internal/Enricher.cs | 7 +++---- ...y_registered.DotNet10_0.DotNet.verified.txt | 18 ++++++++++++++++++ ...ly_registered.DotNet8_0.DotNet.verified.txt | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Sentry/Internal/Enricher.cs b/src/Sentry/Internal/Enricher.cs index 269de8fcfa..cc25f3641c 100644 --- a/src/Sentry/Internal/Enricher.cs +++ b/src/Sentry/Internal/Enricher.cs @@ -12,7 +12,7 @@ internal class Enricher private readonly Lazy _runtimeLazy = new(() => { - var current = PlatformAbstractions.SentryRuntime.Current; + var current = SentryRuntime.Current; return new Runtime { Name = current.Name, @@ -36,7 +36,7 @@ public void Apply(IEventLike eventLike) if (!eventLike.Contexts.ContainsKey(OperatingSystem.Type)) { // RuntimeInformation.OSDescription is throwing on Mono 5.12 - if (!PlatformAbstractions.SentryRuntime.Current.IsMono()) + if (!SentryRuntime.Current.IsMono()) { #if NETFRAMEWORK // RuntimeInformation.* throws on .NET Framework on macOS/Linux @@ -58,9 +58,8 @@ public void Apply(IEventLike eventLike) } } - // SDK // SDK Name/Version might have be already set by an outer package - // e.g: ASP.NET Core can set itself as the SDK + // e.g.: ASP.NET Core can set itself as the SDK if (eventLike.Sdk.Version is null && eventLike.Sdk.Name is null) { eventLike.Sdk.Name = Constants.SdkName; diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt index f477fddad0..113305919d 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt @@ -37,5 +37,23 @@ Args: [ SentryDiagnosticListenerIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt index f477fddad0..113305919d 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt @@ -37,5 +37,23 @@ Args: [ SentryDiagnosticListenerIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file From 7b2e38d48cdbcd237a427fc8d4e6af0d03b3232a Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 12:36:42 +1300 Subject: [PATCH 3/8] Windows verify files --- ...ered.DotNet10_0.Windows.DotNet.verified.txt | 18 ++++++++++++++++++ ...tered.DotNet8_0.Windows.DotNet.verified.txt | 18 ++++++++++++++++++ ...tered.DotNet9_0.Windows.DotNet.verified.txt | 18 ++++++++++++++++++ ..._registered.Net4_8.Windows.Net.verified.txt | 18 ++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt index c1fa278003..03bd2dd921 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt @@ -43,5 +43,23 @@ Args: [ WinUIUnhandledExceptionIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt index c1fa278003..03bd2dd921 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt @@ -43,5 +43,23 @@ Args: [ WinUIUnhandledExceptionIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt index c1fa278003..03bd2dd921 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt @@ -43,5 +43,23 @@ Args: [ WinUIUnhandledExceptionIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt index e9aa248faa..bce3fe85d1 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt @@ -37,5 +37,23 @@ Args: [ NetFxInstallationsIntegration ] + }, + { + Message: Registering integration: '{0}'., + Args: [ + GlobalRootScopeIntegration + ] + }, + { + Message: Created directory for installation ID file ({0})., + Args: [ + {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 + ] + }, + { + Message: Resolved installation ID '{0}'., + Args: [ + Guid_1 + ] } ] \ No newline at end of file From 7a7d0f6c49da39e7ac8963f93a2d1111f4f3bf4f Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 14:17:50 +1300 Subject: [PATCH 4/8] Fix verify files --- ..._registered.DotNet10_0.DotNet.verified.txt | 21 ------------------- ...y_registered.DotNet8_0.DotNet.verified.txt | 21 ------------------- ...y_registered.DotNet9_0.DotNet.verified.txt | 21 ------------------- .../Sentry.Tests/SentryOptionsTests.verify.cs | 2 +- 4 files changed, 1 insertion(+), 64 deletions(-) diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt index 113305919d..ad1db68cad 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -43,17 +34,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt index 113305919d..ad1db68cad 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -43,17 +34,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt index 113305919d..ad1db68cad 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -43,17 +34,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}/Library/Application Support/Sentry/E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.verify.cs b/test/Sentry.Tests/SentryOptionsTests.verify.cs index 3e66a887ba..0ce5d0ce0c 100644 --- a/test/Sentry.Tests/SentryOptionsTests.verify.cs +++ b/test/Sentry.Tests/SentryOptionsTests.verify.cs @@ -16,7 +16,7 @@ public Task Integrations_default_ones_are_properly_registered() }; Hub _ = new(options, Substitute.For()); - var settingsTask = Verify(logger.Entries) + var settingsTask = Verify(logger.Entries.Where(e => e.Message.Contains("Registering integration"))) .UniqueForTargetFrameworkAndVersion() .UniqueForRuntime() .AutoVerify(includeBuildServer: false); From 9907a6c046dd4433452cc617b89e8eb2ff2945da Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 14:25:39 +1300 Subject: [PATCH 5/8] Windows verify files --- ...red.DotNet10_0.Windows.DotNet.verified.txt | 21 ------------------- ...ered.DotNet8_0.Windows.DotNet.verified.txt | 21 ------------------- ...ered.DotNet9_0.Windows.DotNet.verified.txt | 21 ------------------- ...registered.Net4_8.Windows.Net.verified.txt | 21 ------------------- 4 files changed, 84 deletions(-) diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt index 03bd2dd921..a9a8912ac6 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet10_0.Windows.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -49,17 +40,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt index 03bd2dd921..a9a8912ac6 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet8_0.Windows.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -49,17 +40,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt index 03bd2dd921..a9a8912ac6 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.DotNet9_0.Windows.DotNet.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -49,17 +40,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file diff --git a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt index bce3fe85d1..9914267969 100644 --- a/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt +++ b/test/Sentry.Tests/SentryOptionsTests.Integrations_default_ones_are_properly_registered.Net4_8.Windows.Net.verified.txt @@ -1,13 +1,4 @@ [ - { - Message: Initializing Hub for Dsn: '{0}'., - Args: [ - https://d4d82fc1c2c4032a83f3a29aa3a3aff@fake-sentry.io:65535/2147483647 - ] - }, - { - Message: Starting BackpressureMonitor. - }, { Message: Registering integration: '{0}'., Args: [ @@ -43,17 +34,5 @@ Args: [ GlobalRootScopeIntegration ] - }, - { - Message: Created directory for installation ID file ({0})., - Args: [ - {UserProfile}\AppData\Local\Sentry\E071FE7F4BE9BFA6EDB6089C375F386F4142AD01 - ] - }, - { - Message: Resolved installation ID '{0}'., - Args: [ - Guid_1 - ] } ] \ No newline at end of file From 2663ae06564b338e3417b3dd89891c1aba9fbf29 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Thu, 19 Mar 2026 16:40:56 +1300 Subject: [PATCH 6/8] Skip tests on mobile --- test/Sentry.Tests/SentryClientTests.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/Sentry.Tests/SentryClientTests.cs b/test/Sentry.Tests/SentryClientTests.cs index 1fedab2ff8..08e3605761 100644 --- a/test/Sentry.Tests/SentryClientTests.cs +++ b/test/Sentry.Tests/SentryClientTests.cs @@ -302,10 +302,16 @@ public void CaptureEvent_EventAndScope_CopyScopeIntoEvent() Assert.Equal(scope.Breadcrumbs, @event.Breadcrumbs); } - [Fact] + [SkippableFact] public void CaptureEvent_UserIsNull_SetsFallbackUserId() { + // In global mode the userid gets set at app startup via the GlobalRootScopeIntegration, rather than by an + // enricher during capture... so this functionality in SentryClient only works when IsGlobalModeEnabled is false + Skip.If(System.OperatingSystem.IsAndroid() || System.OperatingSystem.IsIOS(), + "On mobile, User.Id is set by GlobalRootScopeIntegration at startup, not the enricher."); + // Arrange + _fixture.SentryOptions.IsGlobalModeEnabled = false; var scope = new Scope(_fixture.SentryOptions); var @event = new SentryEvent(); @@ -1293,10 +1299,16 @@ public void CaptureTransaction_ScopeContainsAttachments_GetAppliedToHint() hint.Attachments.Should().Contain(attachments); } - [Fact] + [SkippableFact] public void CaptureTransaction_UserIsNull_SetsFallbackUserId() { + Skip.If(System.OperatingSystem.IsAndroid() || System.OperatingSystem.IsIOS(), + "On mobile, User.Id is set by GlobalRootScopeIntegration at startup, not the enricher."); + // Arrange + // In global mode the userid gets set at app startup via the GlobalRootScopeIntegration, rather than by an + // enricher during capture... so this functionality in SentryClient only works when IsGlobalModeEnabled is false + _fixture.SentryOptions.IsGlobalModeEnabled = false; var transaction = new SentryTransaction("name", "operation") { IsSampled = true, From abca943c10e6dea1e6d407ca029ad51223f0c690 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Mon, 23 Mar 2026 15:09:06 +1300 Subject: [PATCH 7/8] Fixed build on NetFX/Standard --- src/Sentry/PlatformAbstractions/FrameworkInfo.cs | 3 ++- test/Sentry.Tests/SentryClientTests.cs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Sentry/PlatformAbstractions/FrameworkInfo.cs b/src/Sentry/PlatformAbstractions/FrameworkInfo.cs index 6eb543c443..5b301bff90 100644 --- a/src/Sentry/PlatformAbstractions/FrameworkInfo.cs +++ b/src/Sentry/PlatformAbstractions/FrameworkInfo.cs @@ -36,6 +36,7 @@ public static partial class FrameworkInfo {528372, "4.8"}, {528449, "4.8"}, {533320, "4.8.1"}, - {533325, "4.8.1"} + {533325, "4.8.1"}, + {533509, "4.8.1"} }; } diff --git a/test/Sentry.Tests/SentryClientTests.cs b/test/Sentry.Tests/SentryClientTests.cs index 08e3605761..865f2f7c5e 100644 --- a/test/Sentry.Tests/SentryClientTests.cs +++ b/test/Sentry.Tests/SentryClientTests.cs @@ -1,4 +1,3 @@ -using NSubstitute.ReceivedExtensions; using Sentry.Internal.Http; using BackgroundWorker = Sentry.Internal.BackgroundWorker; @@ -305,11 +304,12 @@ public void CaptureEvent_EventAndScope_CopyScopeIntoEvent() [SkippableFact] public void CaptureEvent_UserIsNull_SetsFallbackUserId() { +#if NET5_0_OR_GREATER // In global mode the userid gets set at app startup via the GlobalRootScopeIntegration, rather than by an // enricher during capture... so this functionality in SentryClient only works when IsGlobalModeEnabled is false Skip.If(System.OperatingSystem.IsAndroid() || System.OperatingSystem.IsIOS(), "On mobile, User.Id is set by GlobalRootScopeIntegration at startup, not the enricher."); - +#endif // Arrange _fixture.SentryOptions.IsGlobalModeEnabled = false; var scope = new Scope(_fixture.SentryOptions); @@ -1302,9 +1302,10 @@ public void CaptureTransaction_ScopeContainsAttachments_GetAppliedToHint() [SkippableFact] public void CaptureTransaction_UserIsNull_SetsFallbackUserId() { +#if NET5_0_OR_GREATER Skip.If(System.OperatingSystem.IsAndroid() || System.OperatingSystem.IsIOS(), "On mobile, User.Id is set by GlobalRootScopeIntegration at startup, not the enricher."); - +#endif // Arrange // In global mode the userid gets set at app startup via the GlobalRootScopeIntegration, rather than by an // enricher during capture... so this functionality in SentryClient only works when IsGlobalModeEnabled is false From 8c2d66b00b527b0bb4e957dd7c13fa01b1605748 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Mon, 23 Mar 2026 20:16:55 +1300 Subject: [PATCH 8/8] Update src/Sentry/Internal/Enricher.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Sentry/Internal/Enricher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Internal/Enricher.cs b/src/Sentry/Internal/Enricher.cs index cc25f3641c..480b92c608 100644 --- a/src/Sentry/Internal/Enricher.cs +++ b/src/Sentry/Internal/Enricher.cs @@ -91,7 +91,7 @@ public void Apply(IEventLike eventLike) eventLike.User.IpAddress ??= DefaultIpAddress; } - // Set by the GlobalRootScopeIntegration In global mode so that it can be overridden by the user. + // Set by the GlobalRootScopeIntegration in global mode so that it can be overridden by the user. // In non-global mode (e.g. ASP.NET Core) the enricher sets it here as a fallback. if (!_options.IsGlobalModeEnabled) {