Skip to content

feat: Add SentrySDK.lastRunStatus to distinguish unknown, no-crash and crash#7469

Open
denrase wants to merge 11 commits intomainfrom
fix/last-run-status
Open

feat: Add SentrySDK.lastRunStatus to distinguish unknown, no-crash and crash#7469
denrase wants to merge 11 commits intomainfrom
fix/last-run-status

Conversation

@denrase
Copy link
Collaborator

@denrase denrase commented Feb 16, 2026

📜 Description

SentrySDK.crashedLastRun returns false both when the app didn't crash and when the status is unknown (before SDK init). This adds SentrySDK.lastRunStatus returning a tri-state enum (.unknown, .didNotCrash, .didCrash) and an onLastRunStatus callback that fires regardless of crash outcome. The old crashedLastRun and onCrashedLastRun are deprecated.

💡 Motivation and Context

Closes #4958

💚 How did you test it?

Unit tests + added logging in sample app.

Bildschirmfoto 2026-02-16 um 17 07 47

📝 Checklist

You have to check all boxes before merging:

  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

…& crash

SentrySDK.crashedLastRun returns false both when the app didn't crash and when the status is unknown (before SDK init). This adds SentrySDK.lastRunStatus returning a tri-state enum (.unknown, .didNotCrash, .didCrash) and an onLastRunStatus callback that fires regardless of crash
 outcome. The old crashedLastRun and onCrashedLastRun are deprecated.

 Closes #4958
@github-actions
Copy link
Contributor

github-actions bot commented Feb 16, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (SPM) Add package traits for UI framework opt-out and macOS CLI sample by philprime in #7578
  • Add SentrySDK.lastRunStatus to distinguish unknown, no-crash and crash by denrase in #7469
  • Use full flamegraph for metrickit app hangs by noahsmartin in #7185

Bug Fixes 🐛

  • Capture transactions during launch profiling window by philipphofmann in #7602

Internal Changes 🔧

Deps

  • Bump fastlane-plugin-sentry from 2.1.1 to 2.2.0 by dependabot in #7626
  • Bump mikepenz/action-junit-report from 6.3.0 to 6.3.1 by dependabot in #7630
  • Bump actions/setup-node from 6.2.0 to 6.3.0 by dependabot in #7627
  • Bump getsentry/craft/.github/workflows/changelog-preview.yml from 2.23.0 to 2.23.2 by dependabot in #7628
  • Bump getsentry/craft from 2.23.0 to 2.23.2 by dependabot in #7629
  • Bump ruby/setup-ruby from 1.288.0 to 1.290.0 by dependabot in #7631

Samples

  • Restructure iOS-SwiftUI-Widgets sample by philprime in #7658
  • Restructure iOS15-SwiftUI sample by philprime in #7657
  • Restructure watchOS-Swift sample by philprime in #7614
  • Restructure visionOS-Swift sample by philprime in #7616
  • Restructure visionOS-SwiftUI-SPM sample by philprime in #7615

Other

  • (ci) Adds a Nightly Job with unit tests for less frequent devices by itaybre in #7632
  • (test-samples) Restructure SwiftUITestSample and SwiftUICrashTest by philprime in #7612
  • Fix watchOS tests and add them to nightly job by itaybre in #7633
  • Add crash when SentryInitializeForGettingSubclassesNotCalled is… by noahsmartin in #7637
  • Fix flaky HangTracker deallocated test by noahsmartin in #7639

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 16, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against d205c44

@available(*, deprecated, message: "Use onLastRunStatus instead, which is called regardless of whether the app crashed.")
@objc public var onCrashedLastRun: SentryOnCrashedLastRunCallback?

/// A block called shortly after the initialization of the SDK when the crash status of the
Copy link
Collaborator Author

@denrase denrase Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if there's enough value in also calling it for normal program execution (not crashed), but added if for completnes sake. If we don't need it, we keep calling onCrashedLastRun like before and not deprecate it.

@denrase denrase added the ready-to-merge Use this label to trigger all PR workflows label Feb 16, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 16, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1218.73 ms 1256.80 ms 38.07 ms
Size 24.14 KiB 1.12 MiB 1.10 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
795e128 1216.68 ms 1245.83 ms 29.15 ms
0e4a9dc 1222.92 ms 1255.78 ms 32.86 ms
7e30a5e 1214.57 ms 1247.78 ms 33.21 ms
79e2bb8 1216.37 ms 1242.42 ms 26.05 ms
64e79c5 1217.59 ms 1243.98 ms 26.39 ms
6108e4c 1212.31 ms 1251.80 ms 39.49 ms
84bc307 1211.52 ms 1237.09 ms 25.56 ms
fee8669 1220.50 ms 1231.84 ms 11.34 ms
80963bd 1194.76 ms 1212.13 ms 17.38 ms
e03f459 1222.56 ms 1255.94 ms 33.37 ms

App size

Revision Plain With Sentry Diff
795e128 24.14 KiB 1.10 MiB 1.08 MiB
0e4a9dc 24.14 KiB 1.11 MiB 1.09 MiB
7e30a5e 24.14 KiB 1.10 MiB 1.08 MiB
79e2bb8 24.14 KiB 1.04 MiB 1.02 MiB
64e79c5 24.14 KiB 1.11 MiB 1.09 MiB
6108e4c 24.14 KiB 1.11 MiB 1.09 MiB
84bc307 24.14 KiB 1.08 MiB 1.06 MiB
fee8669 24.14 KiB 1.10 MiB 1.08 MiB
80963bd 24.14 KiB 1.11 MiB 1.09 MiB
e03f459 24.14 KiB 1.11 MiB 1.09 MiB

Previous results on branch: fix/last-run-status

Startup times

Revision Plain With Sentry Diff
0d5824a 1212.98 ms 1249.57 ms 36.59 ms

App size

Revision Plain With Sentry Diff
0d5824a 24.14 KiB 1.11 MiB 1.09 MiB

@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

❌ Patch coverage is 88.09524% with 5 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@316a9d6). Learn more about missing BASE report.
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
Sources/Swift/Helper/SentryLastRunStatus.swift 0.000% 5 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##             main     #7469   +/-   ##
========================================
  Coverage        ?   85.995%           
========================================
  Files           ?       484           
  Lines           ?     28820           
  Branches        ?     12519           
========================================
  Hits            ?     24784           
  Misses          ?      3988           
  Partials        ?        48           
Files with missing lines Coverage Δ
SentryTestUtils/Sources/ClearTestState.swift 83.720% <100.000%> (ø)
Sources/Sentry/SentryClient.m 98.736% <100.000%> (ø)
Sources/Sentry/SentryOptionsInternal.m 99.479% <100.000%> (ø)
Sources/Sentry/SentrySDKInternal.m 84.684% <100.000%> (ø)
Sources/Swift/Helper/SentrySDK.swift 84.545% <100.000%> (ø)
...egrations/SentryCrash/SentryCrashIntegration.swift 96.899% <100.000%> (ø)
Sources/Swift/Options.swift 100.000% <ø> (ø)
Sources/Swift/Helper/SentryLastRunStatus.swift 0.000% <0.000%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 316a9d6...d205c44. Read the comment docs.

@denrase denrase marked this pull request as ready for review February 17, 2026 13:23
Copilot AI review requested due to automatic review settings February 23, 2026 13:10
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a new tri-state enum SentryLastRunStatus to address the limitation of the boolean crashedLastRun property, which could not distinguish between "did not crash" and "unknown" (before SDK initialization). The change is backward compatible, with the old APIs deprecated but still functional.

Changes:

  • Adds SentryLastRunStatus enum with three cases: .unknown, .didNotCrash, and .didCrash
  • Adds SentrySDK.lastRunStatus property that returns the tri-state enum
  • Adds Options.onLastRunStatus callback that is invoked regardless of crash status (unlike the old callback which only fired on crashes)
  • Deprecates SentrySDK.crashedLastRun and Options.onCrashedLastRun with clear migration guidance

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Sources/Swift/Helper/SentryLastRunStatus.swift Defines new SentryLastRunStatus enum with documentation and CustomStringConvertible conformance
Sources/Swift/Helper/SentrySDK.swift Adds lastRunStatus property and deprecates crashedLastRun with migration guidance
Sources/Swift/Options.swift Adds onLastRunStatus callback and deprecates onCrashedLastRun
Sources/Sentry/include/SentrySDKInternal.h Updates Objective-C header with new lastRunStatus property and deprecation markers
Sources/Sentry/include/SentrySDK+Private.h Renames crashedLastRunCalled to lastRunStatusCalled and adds crashReporterInstalled flag
Sources/Sentry/SentrySDKInternal.m Implements lastRunStatus with proper state checking and resets flags in close()
Sources/Sentry/SentryOptionsInternal.m Adds options parsing for onLastRunStatus callback
Sources/Sentry/SentryClient.m Updates callback invocation to call both old and new callbacks for backward compatibility
Sources/Swift/Integrations/SentryCrash/SentryCrashIntegration.swift Sets crashReporterInstalled flag and calls onLastRunStatus callback for non-crash scenarios
Tests/SentryTests/SentrySDKTests.swift Adds tests for lastRunStatus in various states
Tests/SentryTests/SentryOptionsTest.m Adds tests for onLastRunStatus options parsing
Tests/SentryTests/SentryClientTests.swift Adds comprehensive tests for onLastRunStatus callback behavior
Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift Adds tests for integration's handling of onLastRunStatus
SentryTestUtils/Sources/ClearTestState.swift Updates test cleanup to reset new flags
Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift Demonstrates new API usage with logging
CHANGELOG.md Adds feature entry

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@denrase denrase requested a review from itaybre February 23, 2026 13:26
@sentry
Copy link

sentry bot commented Mar 10, 2026

Sentry Build Distribution

App Version Configuration
App 9.6.0 (1) Release

@sentry
Copy link

sentry bot commented Mar 10, 2026

Sentry Build Distribution

App Version Configuration
App 9.6.0 (1) Release

@sentry
Copy link

sentry bot commented Mar 10, 2026

Sentry Build Distribution

App Version Configuration
App 9.6.0 (1) Release

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

if !SentryDependencyContainer.sharedInstance().crashWrapper.crashedLastLaunch, let callback = options?.onLastRunStatusDetermined {
SentrySDKInternal.lastRunStatusCalled = true
callback(.didNotCrash, nil)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No-crash callback silently suppresses deprecated callback for fatal events

Medium Severity

When both onLastRunStatusDetermined and the deprecated onCrashedLastRun are set and the crash reporter reports no crash, lastRunStatusCalled is set to true in the integration. If a non-crash-reporter fatal event (like a watchdog termination) arrives later in SentryClient, the !lastRunStatusCalled guard causes the entire block to be skipped — silently suppressing the deprecated onCrashedLastRun callback that would have fired before this change. Previously, crashedLastRunCalled was only set inside SentryClient when onCrashedLastRun was non-nil, so it never blocked later fatal events when only the deprecated callback was in use alongside no early flag-setting code.

Additional Locations (1)

Fix in Cursor Fix in Web

@sentry
Copy link

sentry bot commented Mar 10, 2026

Sentry Build Distribution

App Version Configuration
App 9.6.0 (1) Release

Copy link
Contributor

@itaybre itaybre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I am fine with resetting lastRunStatusCalled status.
Maybe just add a note regarding the expected behavior

[SentrySDKInternal setCurrentHub:nil];

crashReporterInstalled = NO;
lastRunStatusCalled = NO;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: This means that closing and starting the SDK will call onLastRunStatus again right?
But in theory it will always return false (if the SDK closed and started again, it would be old to have crashed)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, i will check & address this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Use this label to trigger all PR workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

crashedLastRun returns unreliable and unexpected values and shows undocumented behavior

3 participants