Skip to content

[merge after iOS SDK 7.0.0-beta7] logException: domain only, as in the 7.x SDKs (no labels, no includeVideo) - #89

Closed
dsheikherev wants to merge 4 commits into
chore/ios-beta6-android-pr265from
fix/log-exception-sdk-api
Closed

dsheikherev wants to merge 4 commits into
chore/ios-beta6-android-pr265from
fix/log-exception-sdk-api

Conversation

@dsheikherev

@dsheikherev dsheikherev commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Adapts the wrapper to the 7.x logException APIs, now the same shape on both platforms: a domain and skipFrames, no labels, no includeVideo.

Draft. Stacked on #81. The iOS side needs an SDK release that does not exist yet: 7.0.0-beta7 with bugsee/bugsee-cocoa#233 (and #232, #234 under/over it), where BugseeExceptionLoggingOptions and the options: overloads are removed and logException:reason:domain:skipFrames:completion: is new. Until native-versions.json moves to it, the four iOS build jobs fail on that one call (BugseeModule.mm:1371: no known class method for selector 'logException:reason:domain:skipFrames:completion:') — expected. Do not merge before the SDK PRs.

The Android side needs nothing new: the pinned 7.4.1 already has logException(Throwable, String domain, int skipFrames) (bugsee/bugsee-android#256), and the android job compiles BugseeModule.java against it.

Changes

  1. JS (feat(exceptions)!): ExceptionOptions is {domain?}. labels and includeVideo are unknown keys and throw TypeError; a report is labelled in setReportHandler. The wrapper is unpublished (0.0.0).
    • e2e: the labels cases are gone (exceptions case 7, [API-13d]); [API-11d] checks that includeVideo is refused and files nothing (runFor waits for 3 bundles, not 5); the scenarios stop passing labels (staging finds its report by the campaign text, not by labels).
    • Playground: the includeVideo and labels actions and the cocoa-226 / android-247 known issues are gone; the shop and the boundary demo use a domain.
  2. iOS (fix(ios)): BGSRNExceptions parses {domain?} into BGSRNExceptionOptions; BugseeModule.mm calls logException:reason:domain:skipFrames:completion: with skipFrames 0. Comments: beta7 accepts logException while Launching (cocoa#234), so BGSRNLaunchHold stays only for call order and for createReport / showReportDialog; the simulator now calls logUnhandledException's completion (cocoa#232), BGSRNSettleOnce stays. e2e asserts the report's exception options carry no includeVideo.
  3. Android (fix(android)): ExceptionBridge parses {domain?} and calls logException(Throwable, String, int) with skipFrames 0.
  4. Design doc §9.1 follows.

skipFrames is always 0: it leaves top native frames out of the report's signature, and an RN report is keyed on the JS signature in the payload.

Verification (local)

  • yarn lint, yarn typecheck, yarn test: 3577 passed.
  • iOS BugseeRNSupport (xcodebuild, iOS 26.5 simulator): 322/0 — the Support package no longer references SDK option types, so it builds against beta6 too.
  • Android :bugsee-android-bridge + :bugsee-android-feedback unit tests: pass (BugseeModule.java is excluded there).
  • iOS example (generic device, Debug) against a Bugsee.xcframework built from the SDK stack tip (cocoa fix/log-exception-while-launching): BugseeModule.mm compiles and links, and the binary calls logException:reason:domain:skipFrames:completion:. Only the JS bundle phase failed (no credentials.json without BUGSEE_TOKEN_IOS).
  • CI: android (incl. assembleDebug, so BugseeModule.java against 7.4.1), ios unit (BugseeRNSupport), lint/typecheck/unit, mutation, pack install — pass; the four iOS build jobs fail only on the beta7 call above.
  • Not run: the device e2e.
  • Reviewed locally by a Fable sub-agent over several rounds; the findings are applied.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Behavior Changes
    • logException now accepts only the optional domain setting. Calls that include labels or includeVideo are no longer supported.
    • Use setReportHandler to apply labels to reports.
    • Individual exception reports can no longer exclude video.
  • Examples
    • Updated error-reporting examples to use domains instead of labels; removed demonstrations of unsupported options.

dsheikherev and others added 4 commits October 15, 2026 00:16
Neither 7.x SDK's logException takes labels or can leave the video out of
one report any more (bugsee-cocoa#233, bugsee-android#256). JS
ExceptionOptions is {domain?}; labels and includeVideo are unknown keys
and throw TypeError, like any other. A report is labelled in
setReportHandler.

e2e: the labels cases (exceptions case 7, [API-13d]) are gone, [API-11d]
checks that includeVideo is refused and files nothing, and the scenarios
stop passing labels. Playground: the includeVideo and labels actions and
their known issues are gone; the shop and the boundary demo use a domain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.0.0-beta7 removes BugseeExceptionLoggingOptions and the options:
overloads (bugsee-cocoa#233). The bridge parses {domain?} into its own
BGSRNExceptionOptions, ignoring any other key, and calls
logException:reason:domain:skipFrames:completion: with skipFrames 0: it
leaves top native frames out of the report's signature, and an RN report
is keyed on the JS signature in the payload. The e2e checks that the
report's exception options no longer carry includeVideo.

Comments only: beta7 accepts logException while the SDK is Launching
(bugsee-cocoa#234), so BGSRNLaunchHold now holds it only for the order of
calls and for createReport/showReportDialog, which still need Launched;
the simulator calls logUnhandledException's completion (bugsee-cocoa#232),
and BGSRNSettleOnce stays so a promise settles exactly once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugsee-android#256 deprecates logException(Throwable, Map), whose labels
and includeVideo were never applied, for logException(Throwable, String
domain, int skipFrames). The bridge parses {domain?} and calls the new
overload with skipFrames 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n APIs

§9.1 names the iOS 7.0.0-beta7 and Android #256 overloads the bridges
call, and ExceptionOptions is {domain?}; the Removed list adds
logException's labels and includeVideo options.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c7c7c1e3-55a1-4683-aff1-a25744b07b0f
📥 Commits

Reviewing files that changed from the base of the PR and between 0dd7f86 and b96d834.

📒 Files selected for processing: 28
  • docs/design/2026-09-15-sdk-design.md
  • examples/bare/e2e/api-arguments.test.ts
  • examples/bare/e2e/exceptions.test.ts
  • examples/bare/scenarios/api-args.ts
  • examples/bare/scenarios/api.tsx
  • examples/bare/scenarios/exceptions.tsx
  • examples/bare/scenarios/staging.ts
  • examples/playground/README.md
  • examples/playground/__tests__/errors.test.tsx
  • examples/playground/__tests__/shop.flow.test.ts
  • examples/playground/__tests__/shop.screens.test.tsx
  • examples/playground/src/screens/ErrorsScreen.tsx
  • examples/playground/src/screens/shop/Products.tsx
  • examples/playground/src/shop/flow.ts
  • examples/playground/src/ui/knownIssues.ts
  • packages/react-native/android/src/main/java/com/bugsee/reactnative/BugseeModule.java
  • packages/react-native/android/src/main/java/com/bugsee/reactnative/ExceptionBridge.java
  • packages/react-native/android/src/test/java/com/bugsee/reactnative/ExceptionBridgeTest.java
  • packages/react-native/ios/BugseeModule.mm
  • packages/react-native/ios/Support/Sources/BugseeRNSupport/BGSRNExceptions.m
  • packages/react-native/ios/Support/Sources/BugseeRNSupport/include/BGSRNExceptions.h
  • packages/react-native/ios/Support/Sources/BugseeRNSupport/include/BGSRNLaunchHold.h
  • packages/react-native/ios/Support/Tests/BugseeRNSupportTests/BGSRNExceptionsTests.m
  • packages/react-native/src/NativeBugsee.ts
  • packages/react-native/src/exceptions/__tests__/ErrorBoundary.test.tsx
  • packages/react-native/src/exceptions/__tests__/options.test.ts
  • packages/react-native/src/exceptions/__tests__/report.test.ts
  • packages/react-native/src/exceptions/options.ts
💤 Files with no reviewable changes: 3
  • examples/playground/README.md
  • examples/playground/src/ui/knownIssues.ts
  • examples/bare/scenarios/exceptions.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The logException options contract now supports only an optional domain. Android and iOS pass that domain to their SDK overloads with skipFrames set to zero. Tests and examples now reflect the removal of labels and includeVideo options.

Changes: Handled exception options

Layer / File(s) Summary
Narrow the options contract
packages/react-native/src/exceptions/options.ts, packages/react-native/src/exceptions/__tests__/*, packages/react-native/src/NativeBugsee.ts, packages/react-native/src/exceptions/__tests__/report.test.ts, packages/react-native/src/exceptions/__tests__/ErrorBoundary.test.tsx, docs/design/2026-09-15-sdk-design.md
ExceptionOptions and its encoder now allow only domain. Tests and design documentation describe the domain-only options shape.
Parse and forward domain on native bridges
packages/react-native/ios/Support/Sources/BugseeRNSupport/*, packages/react-native/ios/BugseeModule.mm, packages/react-native/ios/Support/Tests/BugseeRNSupportTests/*, packages/react-native/android/src/main/java/com/bugsee/reactnative/*, packages/react-native/android/src/test/java/com/bugsee/reactnative/*
The native bridges parse domain and pass it to the SDK with skipFrames set to zero. Native tests cover the parsed options and recorded calls.
Align examples and end-to-end coverage
examples/bare/e2e/*, examples/bare/scenarios/*, examples/playground/README.md, examples/playground/__tests__/*, examples/playground/src/screens/ErrorsScreen.tsx, examples/playground/src/screens/shop/Products.tsx, examples/playground/src/shop/flow.ts, examples/playground/src/ui/knownIssues.ts
Example calls and assertions no longer rely on handled-exception labels or includeVideo options. End-to-end tests expect includeVideo calls to fail.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Other

Suggested reviewers: krassx

Merge Risk: ⚪ Minimal · up to b96d8

No confirmed defect remains. Confirm the changed iOS call against the pinned SDK before release.

Security architecture risk: 🔵 Low · up to b96d8

The API change does not show a new privilege or data-access path. Risk remains low rather than minimal because compatibility with required releases and their video-handling behavior still need confirmation.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure remains application-supplied exception data entering the existing reporting SDK. Changed examples substitute domain metadata or remove unsupported actions; they do not show new authentication, tenant-selection, credential, or administrative authority. Downstream storage and video behavior cannot be bounded from the inspected wrapper alone.

Trust Boundaries and Controls

  • observed — JavaScript enforces the supported option names and domain length before bridge invocation. Native parsing checks the domain's runtime type but ignores unknown keys and continues reporting without domain after malformed options. That reporting fallback predates this PR; the head does not establish native schema parsing as an authorization or privacy boundary.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.93% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 27 functions across 21 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main change: adapting logException to the iOS SDK 7.0.0-beta7 and 7.x domain-only API while removing labels and includeVideo.
Full details: Docstring Coverage

Explanation

Docstring coverage is 25.93% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 27 functions across 21 files. (4 skipped: 4 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@dsheikherev
dsheikherev marked this pull request as ready for review October 14, 2026 17:18

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Deep review — b96d834

Intent is correct: ExceptionOptions becomes {domain?} to match the converged 7.x logException APIs (cocoa#233, android#256). Labels and includeVideo are unknown keys (TypeError, nothing crosses). Both bridges pass the domain and skipFrames 0. The package is still unpublished (0.0.0).

Reviewed against callers (Bugsee.logException, ErrorBoundary, reportHandled), the 7.4.1 Android javadoc, cocoa#233/#234 notes, BGSRNLaunchHold, e2e/playground fallout, and CI on this SHA. Diff was not reviewed in isolation.

Findings

No P0–P3 defects in the unique code.

Adversarial checks that did not land as defects:

  • Null domain on the Android 3-arg API. ExceptionBridge always calls logException(t, domain, 0) with domain == null when JS sent no options. 7.4.1 javadoc marks that String @Nullable (“May be null”). Negatives clamp to 0. CI android and playground Android build are green on this SHA — 7.4.1 already has the overload (it shipped in 7.4.0). The PR body’s “Android assembleDebug cannot compile until a post-7.4.1 release” is stale; only iOS is blocked on a pin.
  • skipFrames 0. Android javadoc: skipFrames is “how many top frames of the exception’s own stack to leave out of the report’s signature.” 0 includes every native frame of ReactNativeWebException (constructed at one bridge site). That matches the old Map path with skipFrames absent. RN grouping is the JS payload (ReactNativeWebException + worker); skipFrames cannot uniquify JS errors anyway.
  • Malformed / empty options. JS encodes undefined/{} as null. Native: nil JSON → no domain; {} → Options with nil domain; bad JSON / wrong-typed domain → log and still send. iOS opts.domain on a nil opts is messaging-nil. Same never-throw contract as before.
  • Labels / includeVideo TypeError. Matches the existing unknown-key policy. TypeScript rejects the old fields. ErrorBoundary already reports without options when encode throws, so a leftover labels on the boundary drops the domain too — same as any other bad option, and this wrapper is 0.0.0. Replacement path is setReportHandler (Report.addLabels); that is what 7.4.1 javadoc and cocoa#233 specify.
  • BGSRNLaunchHold still queues logException during Launching after cocoa#234. Intentional: keeps order with createReport / showReportDialog, which still need Launched. Drop-on-failed-launch is the same window as today. The “sent” NSLog still requires Launched; the hold still prevents the Launching path, so e2e exception handled sent and early-report stay consistent.

Merge-order residual (not a code defect)

native-versions.json still pins iOS 7.0.0-beta6. BugseeModule.mm calls logException:reason:domain:skipFrames:completion:, which is 7.0.0-beta7 (cocoa#233; #232/#234 under/over it). BugseeRNSupport no longer references SDK option types — iOS unit tests pass against beta6. iOS SPM / playground iOS build are red until the pin moves. Do not merge before that.

Device e2e was not run (author). JS lint/typecheck/unit and Android CI were green on this SHA; I did not re-run them locally (no node_modules in this environment).


  1. Overall risk: Low (unique logic). iOS app compile is merge-order, not a logic bug.
  2. Merge recommendation: Approve after the iOS pin moves to 7.0.0-beta7. Keep stacked on #81. Android does not need to wait for a later SDK.
  3. Most important to fix before merge: Bump the iOS pin (and only then land). Nothing else in this tree.
  4. Positive: JS / iOS Support / Android bridge stay in lockstep; unknown keys are ignored natively so a future JS field cannot refuse a report; playground, e2e, and design §9.1 were updated with the API rather than left asserting removed behaviour.
Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@dsheikherev dsheikherev changed the title logException: domain only, as in the 7.x SDKs (no labels, no includeVideo) [merge after iOS SDK 7.0.0-beta7] logException: domain only, as in the 7.x SDKs (no labels, no includeVideo) Oct 15, 2026
@krassx
krassx deleted the branch chore/ios-beta6-android-pr265 October 15, 2026 12:57
@krassx krassx closed this Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants