From faf01c91a7238380aeda2cd6586ba7dd49eb3711 Mon Sep 17 00:00:00 2001 From: Stefan Jandl Date: Thu, 23 Nov 2023 22:59:17 +0100 Subject: [PATCH] fix: Sessions not getting finished (#2895) --- CHANGELOG.md | 4 +++ src/Sentry/Internal/Hub.cs | 4 +-- test/Sentry.Tests/SentryClientTests.cs | 43 +++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f6f9373b..2efc76d470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- The SDK no longer fails to finish sessions while capturing an event. This fixes broken crash-free rates ([#2895](https://github.com/getsentry/sentry-dotnet/pull/2895)) + ### Dependencies - Bump Cocoa SDK from v8.16.0 to v8.16.1 ([#2891](https://github.com/getsentry/sentry-dotnet/pull/2891)) diff --git a/src/Sentry/Internal/Hub.cs b/src/Sentry/Internal/Hub.cs index 30861ca298..f511d58568 100644 --- a/src/Sentry/Internal/Hub.cs +++ b/src/Sentry/Internal/Hub.cs @@ -47,9 +47,9 @@ internal Hub( _options = options; _randomValuesFactory = randomValuesFactory ?? new SynchronizedRandomValuesFactory(); - _ownedClient = client ?? new SentryClient(options, randomValuesFactory: _randomValuesFactory); - _clock = clock ?? SystemClock.Clock; _sessionManager = sessionManager ?? new GlobalSessionManager(options); + _ownedClient = client ?? new SentryClient(options, randomValuesFactory: _randomValuesFactory, sessionManager: _sessionManager); + _clock = clock ?? SystemClock.Clock; ScopeManager = scopeManager ?? new SentryScopeManager(options, _ownedClient); diff --git a/test/Sentry.Tests/SentryClientTests.cs b/test/Sentry.Tests/SentryClientTests.cs index 8743b0429b..8b5cc632a0 100644 --- a/test/Sentry.Tests/SentryClientTests.cs +++ b/test/Sentry.Tests/SentryClientTests.cs @@ -18,7 +18,7 @@ private class Fixture public IBackgroundWorker BackgroundWorker { get; set; } = Substitute.For(); public IClientReportRecorder ClientReportRecorder { get; } = Substitute.For(); - public ISessionManager SessionManager { get; } = Substitute.For(); + public ISessionManager SessionManager { get; set; } = Substitute.For(); public Fixture() { @@ -699,6 +699,47 @@ public void CaptureEvent_Processing_Order() processingOrder.Should().Equal(expectedOrder); } + [Fact] + public void CaptureEvent_SessionRunningAndHasException_ReportsErrorButDoesNotEndSession() + { + _fixture.BackgroundWorker.EnqueueEnvelope(Arg.Do(envelope => + { + var sessionItems = envelope.Items.Where(x => x.TryGetType() == "session"); + foreach (var item in sessionItems) + { + var session = (SessionUpdate)((JsonSerializable)item.Payload).Source; + Assert.Equal(1, session.ErrorCount); + Assert.Null(session.EndStatus); + } + })); + _fixture.SessionManager = new GlobalSessionManager(_fixture.SentryOptions); + _fixture.SessionManager.StartSession(); + + _fixture.GetSut().CaptureEvent(new SentryEvent(new Exception("test exception"))); + } + + [Fact] + public void CaptureEvent_SessionRunningAndHasTerminalException_ReportsErrorAndEndsSessionAsCrashed() + { + _fixture.BackgroundWorker.EnqueueEnvelope(Arg.Do(envelope => + { + var sessionItems = envelope.Items.Where(x => x.TryGetType() == "session"); + foreach (var item in sessionItems) + { + var session = (SessionUpdate)((JsonSerializable)item.Payload).Source; + Assert.Equal(1, session.ErrorCount); + Assert.NotNull(session.EndStatus); + Assert.Equal(SessionEndStatus.Crashed, session.EndStatus); + } + })); + _fixture.SessionManager = new GlobalSessionManager(_fixture.SentryOptions); + _fixture.SessionManager.StartSession(); + + var exception = new Exception("test exception"); + exception.SetSentryMechanism("test mechanism", handled: false); + _fixture.GetSut().CaptureEvent(new SentryEvent(exception)); + } + [Fact] public void CaptureEvent_Release_SetFromOptions() {