diff --git a/CHANGELOG.md b/CHANGELOG.md index 090d0a36ef..9590e28a67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixes +- Save app context information (release name, dist, environment) on app hang events before saving to disk to prevent incorrect version information when an app hang turns fatal (#6998) - Disabled automatic session tracking in system extensions to prevent extension blocking and unwanted dock icon behavior (#6962) (#6962) - Fixes crash when null values are passed to `UIApplication sendAction:to:from:forEvent:` (#6970) diff --git a/Sources/Sentry/SentryANRTrackingIntegration.m b/Sources/Sentry/SentryANRTrackingIntegration.m index 43a1ad8caa..322b42047d 100644 --- a/Sources/Sentry/SentryANRTrackingIntegration.m +++ b/Sources/Sentry/SentryANRTrackingIntegration.m @@ -180,12 +180,31 @@ - (void)anrDetectedWithType:(enum SentryANRType)type [scope applyToEvent:event maxBreadcrumb:options.maxBreadcrumbs]; } + [self applyOptions:options toEvent:event]; + [self.fileManager storeAppHangEvent:event]; #else [SentrySDK captureEvent:event]; #endif } +- (void)applyOptions:(SentryOptions *)options toEvent:(SentryEvent *)event +{ + // We need to apply the release name now, if the app hang turns into a fatal one + // we might en up submitting a wrong version. + event.releaseName = options.releaseName; + + // Only apply dist if it wasn't set by the Scope previously + if (event.dist == nil && options.dist != nil) { + event.dist = options.dist; + } + + // Only apply environment if it wasn't set by the Scope previously + if (event.environment == nil && options.environment != nil) { + event.environment = options.environment; + } +} + - (void)anrStoppedWithResult:(SentryANRStoppedResult *_Nullable)result { #if SENTRY_HAS_UIKIT diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift index 5726042d5b..b4250affb7 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift @@ -21,6 +21,7 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { options.dsn = SentryANRTrackingIntegrationTests.dsn options.enableAppHangTracking = true options.appHangTimeoutInterval = 4.5 + options.releaseName = "release-name-test" debugImageProvider.debugImages = [TestData.debugImage] } @@ -364,6 +365,24 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { } #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) + func testV2_ANRDetected_StoresAppHangEventInFile() throws { + // Arrange + options.releaseName = "my-release-name-test" + options.environment = "testing-environment" + options.dist = "adhoc" + setUpThreadInspector() + givenInitializedTracker() + + // Act + Dynamic(sut).anrDetectedWithType(SentryANRType.nonFullyBlocking) + + // Assert + let event = try XCTUnwrap(SentrySDKInternal.currentHub().client()?.fileManager.readAppHangEvent()) + XCTAssertEqual(event.releaseName, "my-release-name-test") + XCTAssertEqual(event.environment, "testing-environment") + XCTAssertEqual(event.dist, "adhoc") + } + func testV2_ANRDetected_DoesNotCaptureEvent() throws { // Arrange setUpThreadInspector() @@ -424,6 +443,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { // Ensure we capture the event with an empty scope XCTAssertEqual(scope?.tags.count, 0) XCTAssertEqual(scope?.breadcrumbs().count, 0) + + XCTAssertEqual(event?.releaseName, "release-name-test") } } @@ -472,6 +493,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { // Ensure we capture the event with an empty scope XCTAssertEqual(scope?.tags.count, 0) XCTAssertEqual(scope?.breadcrumbs().count, 0) + + XCTAssertEqual(event?.releaseName, "release-name-test") } } @@ -529,6 +552,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { let breadcrumbs = try XCTUnwrap(event?.breadcrumbs) XCTAssertEqual(1, breadcrumbs.count) XCTAssertEqual("crumb", breadcrumbs.first?.message) + + XCTAssertEqual(event?.releaseName, "release-name-test") } } @@ -566,6 +591,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { let breadcrumbs = try XCTUnwrap(event?.breadcrumbs) XCTAssertEqual(1, breadcrumbs.count) XCTAssertEqual("crumb", breadcrumbs.first?.message) + + XCTAssertEqual(event?.releaseName, "release-name-test") } } @@ -618,6 +645,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { XCTAssertEqual("distinct", actualSession.distinctId) XCTAssertEqual(fixture.currentDate.date(), actualSession.timestamp) XCTAssertEqual("anr_foreground", actualSession.abnormalMechanism) + + XCTAssertEqual(event.releaseName, "release-name-test") } func testV2_ANRDetected_StopNotCalledAndCrashed_SendsNormalAppHangEvent() throws {