From 4f4460d187a99bf0fc33c4a91bb9de53326fa48f Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Tue, 22 Nov 2022 13:55:53 +0100 Subject: [PATCH 1/4] fix: Errors shortly after SentrySDK.init don't affect the session Closes #2150 --- Sources/Sentry/SentryHub.m | 12 +++++++++++- Sources/Sentry/SentrySession.m | 5 +++++ Sources/Sentry/include/SentrySession+Private.h | 2 ++ Tests/SentryTests/SentryHubTests.swift | 13 +++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m index 32982b9b8da..45005ede771 100644 --- a/Sources/Sentry/SentryHub.m +++ b/Sources/Sentry/SentryHub.m @@ -15,6 +15,7 @@ #import "SentrySamplingContext.h" #import "SentryScope.h" #import "SentrySerialization.h" +#import "SentrySession+Private.h" #import "SentryTracer.h" #import "SentryTracesSampler.h" #import "SentryTransaction.h" @@ -33,6 +34,7 @@ @property (nonatomic, strong) id currentDateProvider; @property (nonatomic, strong) NSMutableArray> *installedIntegrations; @property (nonatomic, strong) NSMutableSet *installedIntegrationNames; +@property (nonatomic) NSUInteger errorsBeforeSession; @end @@ -53,6 +55,7 @@ - (instancetype)initWithClient:(nullable SentryClient *)client _installedIntegrationNames = [[NSMutableSet alloc] init]; _crashWrapper = [SentryCrashWrapper sharedInstance]; _tracesSampler = [[SentryTracesSampler alloc] initWithOptions:client.options]; + _errorsBeforeSession = 0; #if SENTRY_TARGET_PROFILING_SUPPORTED if (client.options.isProfilingEnabled) { _profilesSampler = [[SentryProfilesSampler alloc] initWithOptions:client.options]; @@ -93,6 +96,11 @@ - (void)startSession } _session = [[SentrySession alloc] initWithReleaseName:options.releaseName]; + if (_errorsBeforeSession > 0) { + _session.errors = _errorsBeforeSession; + _errorsBeforeSession = 0; + } + NSString *environment = options.environment; if (nil != environment) { _session.environment = environment; @@ -200,7 +208,7 @@ - (nullable SentrySession *)incrementSessionErrors { SentrySession *sessionCopy = nil; @synchronized(_sessionLock) { - if (nil != _session) { + if (_session != nil) { [_session incrementErrors]; [self storeCurrentSession:_session]; sessionCopy = [_session copy]; @@ -447,6 +455,7 @@ - (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope withScope:scope incrementSessionErrors:^(void) { return [self incrementSessionErrors]; }]; } else { + _errorsBeforeSession++; return [client captureError:error withScope:scope]; } } @@ -468,6 +477,7 @@ - (SentryId *)captureException:(NSException *)exception withScope:(SentryScope * withScope:scope incrementSessionErrors:^(void) { return [self incrementSessionErrors]; }]; } else { + _errorsBeforeSession++; return [client captureException:exception withScope:scope]; } } diff --git a/Sources/Sentry/SentrySession.m b/Sources/Sentry/SentrySession.m index 8a65e80676a..bca9eb418d8 100644 --- a/Sources/Sentry/SentrySession.m +++ b/Sources/Sentry/SentrySession.m @@ -22,6 +22,11 @@ } } +@interface +SentrySession () +@property (nonatomic) NSUInteger errors; +@end + @implementation SentrySession @synthesize flagInit = _init; diff --git a/Sources/Sentry/include/SentrySession+Private.h b/Sources/Sentry/include/SentrySession+Private.h index 3a2b277ffa6..063ae4ecd11 100644 --- a/Sources/Sentry/include/SentrySession+Private.h +++ b/Sources/Sentry/include/SentrySession+Private.h @@ -8,6 +8,8 @@ NSString *nameForSentrySessionStatus(SentrySessionStatus status); @interface SentrySession (Private) +@property (nonatomic) NSUInteger errors; + - (void)setFlagInit; @end diff --git a/Tests/SentryTests/SentryHubTests.swift b/Tests/SentryTests/SentryHubTests.swift index e0d5565a3eb..2e16a612750 100644 --- a/Tests/SentryTests/SentryHubTests.swift +++ b/Tests/SentryTests/SentryHubTests.swift @@ -394,6 +394,19 @@ class SentryHubTests: XCTestCase { XCTAssertEqual(1, fixture.client.captureSessionInvocations.count) } + func testCaptureErrorBeforeSession() { + let sut = fixture.getSut() + sut.capture(error: fixture.error, scope: fixture.scope).assertIsNotEmpty() + sut.startSession() + + XCTAssertEqual(fixture.client.captureErrorWithScopeInvocations.count, 1) + XCTAssertEqual(fixture.client.captureSessionInvocations.count, 1) + + if let session = fixture.client.captureSessionInvocations.first { + XCTAssertEqual(session.errors, 1) + } + } + func testCaptureWithoutIncreasingErrorCount() { let sut = fixture.getSut() sut.startSession() From 89e0f700b1820f86595b3b7480117be8e3eaa7dc Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Tue, 22 Nov 2022 13:56:29 +0100 Subject: [PATCH 2/4] Undo --- Sources/Sentry/SentryHub.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m index 45005ede771..00c71093c72 100644 --- a/Sources/Sentry/SentryHub.m +++ b/Sources/Sentry/SentryHub.m @@ -208,7 +208,7 @@ - (nullable SentrySession *)incrementSessionErrors { SentrySession *sessionCopy = nil; @synchronized(_sessionLock) { - if (_session != nil) { + if (nil != _session) { [_session incrementErrors]; [self storeCurrentSession:_session]; sessionCopy = [_session copy]; From 5feef19788bf03f64ba3a96813a590922347c2ae Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Tue, 22 Nov 2022 13:59:30 +0100 Subject: [PATCH 3/4] Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28531f5055b..f0f78e4513a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ This version adds a dependency on Swift. - Properly demangle Swift class name (#2162) +### Fixes + +- Errors shortly after SentrySDK.init now affect the session (#2430) + ### Breaking Changes - Remove `- [SentryOptions initWithDict:didFailWithError:]` (#2404) From 95a3f670576a85ab2f469ccb4bd55ed8a3412b86 Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Wed, 23 Nov 2022 10:20:06 +0100 Subject: [PATCH 4/4] "change this from a category to a class extension (anonymous category) then you don't have to redeclare the property in SentrySession.m; instead, you can just `#include "SentrySession+Private.h"" --- Sources/Sentry/SentrySession.m | 7 +------ Sources/Sentry/include/SentrySession+Private.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Sources/Sentry/SentrySession.m b/Sources/Sentry/SentrySession.m index bca9eb418d8..559dbccba6f 100644 --- a/Sources/Sentry/SentrySession.m +++ b/Sources/Sentry/SentrySession.m @@ -1,8 +1,8 @@ -#import "SentrySession.h" #import "NSDate+SentryExtras.h" #import "SentryCurrentDate.h" #import "SentryInstallation.h" #import "SentryLog.h" +#import "SentrySession+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -22,11 +22,6 @@ } } -@interface -SentrySession () -@property (nonatomic) NSUInteger errors; -@end - @implementation SentrySession @synthesize flagInit = _init; diff --git a/Sources/Sentry/include/SentrySession+Private.h b/Sources/Sentry/include/SentrySession+Private.h index 063ae4ecd11..1075b302614 100644 --- a/Sources/Sentry/include/SentrySession+Private.h +++ b/Sources/Sentry/include/SentrySession+Private.h @@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *nameForSentrySessionStatus(SentrySessionStatus status); @interface -SentrySession (Private) +SentrySession () @property (nonatomic) NSUInteger errors;