chore: [SDK-5022] add demo test crash flow - #1715
Conversation
There was a problem hiding this comment.
Multi-model adversarial review (interrogate)
Intent
Add a deterministic demo test-crash flow that exercises the SDK's uncaught Objective-C exception capture without treating unrelated host-app crashes as OneSignal failures — via a SecondaryView crash action and a
userInfomarker (OSCrashTestMarker) that letsOSLogCrashHandlerpersist marked host-stack exceptions. Unmarked host exceptions stay ignored. Stacked on #1714.
Reviewers
- A:
claude-fable-5-thinking-xhigh(6) - B:
gpt-5.6-sol-xhigh(4) - C:
cursor-grok-4.5-high-fast(7) - D:
claude-opus-5-thinking-high(11)
Act On
- Undeclared public API ships a permanent attribution bypass (A/B/C/D) —
public enum OSCrashTestMarkeris new supported surface on distributedOneSignalOSCore, while the PR checklist leaves Public API changes unchecked. Commit7f205d3aalready did the same gate with aprivate static letexception name and zero public API;a0f0e53ftraded that away. Prefer: (a) OSCore-owned raise helper soisOneSignalAtFaultaccepts the frame with no bypass, (b) restore private name-based marker + string literal in the demo, or (c)@_spi+ document if a symbol is truly required. - Marked crashes are unlabeled in telemetry (A/C/D) — marker is gate-only then discarded;
CrashDatagetsRuntimeException+ host stack + caller reason. Ops cannot filter demo pollution except brittle string match. Name-based predecessor self-labeled viaexceptionType. Stamp a deterministic type/prefix when the marker branch admits the crash, or delete the bypass via the OSCore raise helper. - Wrong-layer OR on the shared fatal path (A/C/D) —
isMarkedTestCrash || isOneSignalAtFaultencodes a demo concern into every uncaught-exception path. Code judo: raise fromOneSignalOSCoreso attribution already works; keephandleattribution-only.
Consider
- Demo is the only app file importing
OneSignalOSCore(C/D) — teaches sub-framework coupling for a string constant. - Unit tests call
handle(...)directly; no raise→handler→persist→relaunch coverage (B/D). Thin cases: no NSNumber bridging, no previous-handler forward assert,reason: nilunlike demo. TEMP_*pbxproj UUID churn vs documentedxcodegen generate(A/B/C/D).- Crash button can fire before remote-logging arms the handler (B) — not unique to this PR, but weakens “deterministic.”
#if DEBUGalone is insufficient — e2e archives Release (D).
Noted
Copyright 2024 on new 2026 file; DateFormatter without en_US_POSIX; RuntimeException Java-ism; bare ActionButton vs SectionCard pattern; build.md / shared Appium ID parity not updated.
Dismissed
- Treating the bypass as a critical third-party “poison” exploit — intentional opt-in for integration apps; the real defect is shipping it as undeclared public supported API with unlabeled payloads.
- Demanding a full Catalyst UI path in this PR — nice-to-have on the #1714 stack, not required for the stated iOS demo flow.
Agreement Map
4/4: public API + checklist gap. 3/4 (A/C/D): unlabeled telemetry after marker discard; prefer deleting the shared-path OR via OSCore-framed raise or private name marker. B uniquely stressed handler-not-armed timing. Strongest judo (C): OSCore raise helper deletes findings 1–3 together.
Verdict: Intent is sound and the marked path works in unit tests, but the userInfo refactor regresses the private name-based design — shipping public API and unlabeled host crashes into the SDK fault pipeline. Prefer the OSCore raise helper or restore private self-labeling before merge.
Sent by Cursor Automation: Automatic PR Review
|
Thanks for this — the demo crash flow looks solid. SecondaryView, the marked vs unmarked host-exception tests, and the manual persist-and-upload-after-relaunch check all make sense for exercising app-crash capture. Two small requests, if you have a chance:
Everything else looks good to me — thank you! |
|
Also @fadi-george were you able to test a crash is captured in both KMP and iOS core code? |
dff8025 to
57ef507
Compare
Allow demo-generated NSExceptions to bypass stack attribution through an explicit userInfo marker while preserving their runtime exception type. Co-authored-by: Cursor <cursoragent@cursor.com>
a0f0e53 to
c45ec8e
Compare
Keep production crash attribution unchanged by moving the synthetic crash origin into an SPI helper instead of bypassing the host-crash filter. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the demo on the standard framework boundary while retaining an SPI-only SDK-originated crash path. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the review in 19d935e and 819ccec:
A truly uncaught |
abdulraqeeb33
left a comment
There was a problem hiding this comment.
Remember, this is not a true test of the crash, the Red app is crashing here and its not the OneSignal SDK (that includes KMP)
There was a problem hiding this comment.
Remember, this is not a true test of the crash, the Red app is crashing here and its not the OneSignal SDK (that includes KMP)
The SDK is crashing here, because this PR added a trigger-able crash to the SDK itself in the swift interface. I am not sure we want to merge this PR by adding one-off test cases to the SDK codebase. I don't really see the need to make this case special than any other manual test we do, unless it's important for Appium testing? Can Appium tests validate this though?


Description
One Line Summary
Adds a marked test-crash flow to the SwiftUI demo app.
Details
Motivation
The demo needs a deterministic way to exercise the SDK's uncaught Objective-C exception capture without treating unrelated host-app crashes as OneSignal failures.
Scope
Adds a secondary demo screen and crash action, plus an explicit
userInfomarker recognized by the crash handler. Unmarked host-app exceptions remain ignored.Other
Stacked on #1714.
Testing
Unit testing
Added crash-handler coverage for marked and unmarked host-app exceptions.
Manual testing
Triggered the demo crash and confirmed it is persisted and uploaded after relaunch.
Affected code checklist
Checklist
Overview
Testing
Final pass
Made with Cursor