diff --git a/CHANGELOG.md b/CHANGELOG.md index e1888be4945..72ff670bd26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Cleanup AppHangTracking properly when closing SDK (#2671) - Add EXC_BAD_ACCESS subtypes to events (#2667) +- Keep status of auto transactions when finishing (#2684) - Fix atomic import error for profiling (#2683) ## 8.1.0 diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 1b3412b7feb..9211cd0dbb8 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -451,6 +451,11 @@ - (BOOL)hasUnfinishedChildSpansToWaitFor - (void)finishInternal { + // Keep existing status of auto generated transactions if set by the user. + if ([self isAutoGeneratedTransaction] && !self.wasFinishCalled + && self.status != kSentrySpanStatusUndefined) { + _finishStatus = self.status; + } [super finishWithStatus:_finishStatus]; if (self.finishCallback) { diff --git a/Tests/SentryTests/Performance/SentryTracerTests.swift b/Tests/SentryTests/Performance/SentryTracerTests.swift index 65a015fc1a1..8de3dfd06e7 100644 --- a/Tests/SentryTests/Performance/SentryTracerTests.swift +++ b/Tests/SentryTests/Performance/SentryTracerTests.swift @@ -216,6 +216,47 @@ class SentryTracerTests: XCTestCase { XCTAssertEqual(sut.status, .ok) } + func testIdleTransactionWithStatus_KeepsStatusWhenAutoFinishing() { + let status = SentrySpanStatus.aborted + let sut = fixture.getSut(idleTimeout: fixture.idleTimeout, dispatchQueueWrapper: fixture.dispatchQueue) + sut.status = status + + let child = sut.startChild(operation: fixture.transactionOperation) + advanceTime(bySeconds: 0.1) + child.finish() + + fixture.dispatchQueue.invokeLastDispatchAfter() + + assertOneTransactionCaptured(sut) + XCTAssertEqual(status, sut.status) + } + + func testWaitForChildrenTransactionWithStatus_OverwriteStatusInFinish() { + let sut = fixture.getSut() + sut.status = .aborted + + let finishstatus = SentrySpanStatus.cancelled + + let child = sut.startChild(operation: fixture.transactionOperation) + advanceTime(bySeconds: 0.1) + child.finish() + + sut.finish(status: finishstatus) + + assertOneTransactionCaptured(sut) + XCTAssertEqual(finishstatus, sut.status) + } + + func testManualTransaction_OverwritesStatusInFinish() { + let sut = fixture.getSut(waitForChildren: false) + sut.status = .aborted + + sut.finish() + + assertOneTransactionCaptured(sut) + XCTAssertEqual(.ok, sut.status) + } + func testFinish_WithoutHub_DoesntCaptureTransaction() { let sut = SentryTracer(transactionContext: fixture.transactionContext, hub: nil, waitForChildren: false)