diff --git a/src/Sentry/Scope.cs b/src/Sentry/Scope.cs index d062290133..e4b51bf74f 100644 --- a/src/Sentry/Scope.cs +++ b/src/Sentry/Scope.cs @@ -144,31 +144,33 @@ public SentryUser User /// public string? Distribution { get; set; } - /// - public string? Environment + private string? _environment; + + /// + public string Environment { - get; - set + get => _environment ?? Options.SettingLocator.GetEnvironment(); + set => SetEnvironment(value); + } + + string? IEventLike.Environment + { + get => Environment; + set => SetEnvironment(value); + } + + private void SetEnvironment(string? environment) + { + if (_environment == environment) { - if (field == value) - { - return; - } + return; + } - if (value is null) - { - Options.LogDebug("Environment cannot be null. Reverting to default value from the options."); - field = Options.Environment; - } - else - { - field = value; - } + _environment = environment; - if (Options is { EnableScopeSync: true, ScopeObserver: { } observer }) - { - observer.SetEnvironment(field); - } + if (Options is { EnableScopeSync: true, ScopeObserver: { } observer }) + { + observer.SetEnvironment(Environment); } } @@ -431,7 +433,7 @@ public void Clear() User = new(); Release = default; Distribution = default; - Environment = default; + SetEnvironment(null); TransactionName = default; Transaction = default; Fingerprint = Array.Empty(); @@ -515,7 +517,17 @@ public void Apply(IEventLike other) other.Release ??= Release; other.Distribution ??= Distribution; - other.Environment ??= Environment; + if (other is Scope otherScope) + { + if (otherScope._environment is null) + { + otherScope.SetEnvironment(_environment); + } + } + else + { + other.Environment ??= Environment; + } other.TransactionName ??= TransactionName; other.Level ??= Level; diff --git a/test/Sentry.AspNetCore.Tests/ScopeExtensionsTests.Populate_RouteData_SetToScope.verified.txt b/test/Sentry.AspNetCore.Tests/ScopeExtensionsTests.Populate_RouteData_SetToScope.verified.txt index 8ba783b0dd..efda02a581 100644 --- a/test/Sentry.AspNetCore.Tests/ScopeExtensionsTests.Populate_RouteData_SetToScope.verified.txt +++ b/test/Sentry.AspNetCore.Tests/ScopeExtensionsTests.Populate_RouteData_SetToScope.verified.txt @@ -4,6 +4,7 @@ QueryString: }, User: {}, + Environment: production, TransactionName: GET Ctrl.Actn, Tags: { route.action: Actn, diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt index 803c8f81b3..efdfc57015 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt @@ -404,7 +404,7 @@ namespace Sentry public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } public string? Distribution { get; set; } - public string? Environment { get; set; } + public string Environment { get; set; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public Sentry.SentryLevel? Level { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt index 803c8f81b3..efdfc57015 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt @@ -404,7 +404,7 @@ namespace Sentry public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } public string? Distribution { get; set; } - public string? Environment { get; set; } + public string Environment { get; set; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public Sentry.SentryLevel? Level { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt index 803c8f81b3..efdfc57015 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt @@ -404,7 +404,7 @@ namespace Sentry public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } public string? Distribution { get; set; } - public string? Environment { get; set; } + public string Environment { get; set; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public Sentry.SentryLevel? Level { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt index 803c8f81b3..efdfc57015 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt @@ -404,7 +404,7 @@ namespace Sentry public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } public string? Distribution { get; set; } - public string? Environment { get; set; } + public string Environment { get; set; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public Sentry.SentryLevel? Level { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt index 89bf5488a8..e9c923778b 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt @@ -392,7 +392,7 @@ namespace Sentry public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } public string? Distribution { get; set; } - public string? Environment { get; set; } + public string Environment { get; set; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public Sentry.SentryLevel? Level { get; set; } diff --git a/test/Sentry.Tests/Protocol/ScopeTests.cs b/test/Sentry.Tests/Protocol/ScopeTests.cs index 4ac9bfae4d..d6b7f26130 100644 --- a/test/Sentry.Tests/Protocol/ScopeTests.cs +++ b/test/Sentry.Tests/Protocol/ScopeTests.cs @@ -958,7 +958,7 @@ public void Apply_Sdk_SourceNone_TargetSingle_DoesNotModifyTarget() } [Fact] - public void Apply_Environment_Null() + public void Apply_Environment_Null_TargetUsesOptionsEnvironment() { var sut = _fixture.GetSut(); sut.Environment = null; @@ -966,7 +966,7 @@ public void Apply_Environment_Null() var target = _fixture.GetSut(); sut.Apply(target); - Assert.Null(target.Environment); + Assert.Equal(target.Options.SettingLocator.GetEnvironment(), target.Environment); } [Fact] diff --git a/test/Sentry.Tests/ScopeTests.cs b/test/Sentry.Tests/ScopeTests.cs index 0e04ec4b34..1ef6924990 100644 --- a/test/Sentry.Tests/ScopeTests.cs +++ b/test/Sentry.Tests/ScopeTests.cs @@ -770,6 +770,45 @@ public void SetEnvironment_Null_ObserverReceivesOptionEnvironment() observer.Received(1).SetEnvironment(Arg.Is(optionsEnvironment)); } + [Fact] + public void Environment_NotSet_ReturnsOptionsEnvironment() + { + var scope = new Scope(new SentryOptions { Environment = "staging" }); + + scope.Environment.Should().Be("staging"); + } + + [Fact] + public void Environment_NotSetInOptions_ReturnsDefaultEnvironment() + { + var scope = new Scope(new SentryOptions()); + + scope.Environment.Should().NotBeNullOrWhiteSpace(); + } + + [Fact] + public void Apply_EnvironmentNotSetOnScope_EventGetsOptionsEnvironment() + { + var scope = new Scope(new SentryOptions { Environment = "staging" }); + var evt = new SentryEvent(); + + scope.Apply(evt); + + evt.Environment.Should().Be("staging"); + } + + [Fact] + public void Apply_EnvironmentSetOnTarget_TargetEnvironmentPreserved() + { + var options = new SentryOptions { Environment = "production" }; + var source = new Scope(options) { Environment = "staging" }; + var target = new Scope(options) { Environment = "development" }; + + source.Apply(target); + + target.Environment.Should().Be("development"); + } + [Fact] public void SetEnvironment_SameValue_ObserverNotifiedOnce() {