Repository navigation
[SDK-822] Stop reporting every switchProject as noisy when no user is identified yet - #1095
Merged
joaodordio merged 2 commits intoNov 6, 2026
Conversation
…fied yet Every switchProject done the documented way logged "the new project's SDK did not start cleanly" at error level and reported .switchedWithWarnings, so .switchedCleanly was unreachable after a real switch. ATG hit this while testing and asked whether it needed fixing before go-live. The switch clears the previous user, then starts the new project, and start() runs the first in-app sync before the app can re-identify from the callback. RequestCreator refuses that request while no identity is set, initialize2 turns the refusal into started == false, and the switch folded it into the result. Nothing was wrong: setEmail from the callback schedules the sync again. A failed start now counts as clean when auth.emailOrUserId is .none, and logs at info. The check goes through auth rather than noUserLoggedIn() because the unknown-user ID also lets the request through, so with it set a failed sync is a genuine failure and still reports warnings and logs an error. The start is evaluated before the teardown result so a genuine failure is logged even when the teardown was noisy too. The existing tests missed it because MockDependencyContainer hands out a MockInAppFetcher that succeeds without a user. The new test builds the real InAppFetcher, and fails without the fix. FailingInAppFetcher now sets an unknown-user identity before failing, so it keeps modelling a genuine failure. CHANGELOG: the warning-cause list gains the real fifth cause, says that nobody identified yet on the new project is not a warning, explains the expected "Both email and userId are nil" log line, and notes that a simulator has no APNs token.
The pre-init path forwards the start result since SDK-758, so on a fresh install switchProject reported .switchedWithWarnings for the same reason the post-switch path did: nobody is identified yet, so the first in-app sync is refused and start() fails. Android reports SWITCHED_CLEANLY in the same situation, because its failure signal is an initialization that times out or throws, and a missing user is neither. SDK-758's parity therefore broke in the case most apps hit first. The pre-init callback now goes through the same startCountsAsClean rule. A start that fails with someone identified, for example a returning user whose sync fails, still reports warnings, which is what SDK-758's existing failure test asserts and still passes. The new test drives a fresh-install pre-init switch through the real InAppFetcher and fails without this change. Kept as its own commit because it narrows behaviour SDK-758 locked in during review, so it can be reviewed or dropped separately. CHANGELOG: the Added bullet for pre-init still said it always reported cleanly, which SDK-758 left stale; both it and the SDK-758 Fixed entry now describe the actual behaviour.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feature/SDK-674-switch-project #1095 +/- ##
==================================================================
+ Coverage 75.03% 75.23% +0.20%
==================================================================
Files 118 118
Lines 10634 10642 +8
==================================================================
+ Hits 7979 8007 +28
+ Misses 2655 2635 -20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Summary
A real
switchProjectalways reported.switchedWithWarningsand logged an error, because the new project's first in-app sync runs before the app has re-identified the user.🎟️ Jira Ticket: SDK-822
📖 Description
ATG hit this while testing a pre-release build and asked whether the warning needed fixing before go-live (Slack). Nothing was broken, but
.switchedCleanlywas unreachable after a real switch.Cause. The switch clears the previous user, then starts the new project.
start()returnsinAppManager.start(), whose first sync goes throughRequestCreator.createGetInAppMessagesRequest, which refuses the request whileauth.emailOrUserIdis.none.initialize2turns that refusal intostarted == false, and the switch folded it into the result. The app'ssetEmailfrom the callback schedules the sync again, so nothing is lost.Fix.
startCountsAsCleancounts a failed start as clean when no identity is set, and logs at info instead of error. It checksauth, notnoUserLoggedIn(): the unknown-user ID also lets the request through, so with it set a failed sync is a genuine failure and still reports warnings and logs an error. The start is evaluated beforeteardownWasClean &&, so a genuine failure is still logged when the teardown was noisy too.Two commits, reviewable separately:
dfdd53a2The post-switch path. This is the ticket scope and the log line ATG saw.4f35ad8cThe pre-init path (switch before anyinitialize). Since SDK-758 it forwards the same start result, so a fresh install reported warnings on iOS while Android reportsSWITCHED_CLEANLY, because Android's failure signal is an initialization that times out or throws and a missing user is neither. This narrows what SDK-758 locked in, so it is its own commit and can be dropped. SDK-758's existing failure test still passes: a start that fails with someone identified still warns.Why the tests missed it.
MockDependencyContainer.createInAppFetcherreturns aMockInAppFetcherthat succeeds without a user, so the real request creation never ran. The new tests subclass it to build the realInAppFetcher.FailingInAppFetchernow sets an unknown-user identity before failing, so it keeps modelling a genuine failure rather than the expected refusal.🧪 How to test?
SwitchProjectGateTests.testASwitchWithNoUserYetOnTheNewProjectReportsCleanly: real fetch path, asserts the result is clean, that no in-app request goes out before identification, and that aftersetEmailfrom the callback the sync goes to project B with B's key. Fails without commit 1, on the result assertion only.SwitchProjectGateTests.testSwitchProjectBeforeInitializeWithNoUserYetReportsCleanly: fresh-install pre-init switch on the real fetch path. Fails without commit 2.Local note: on Xcode 27.2 this repo only runs with
IPHONEOS_DEPLOYMENT_TARGET=15.0passed toxcodebuildand on a pre-iOS-27 simulator (I used iOS 18.5), because Xcode 27 rejects the 12.0 target and the iOS 27 runtime refuses to launch the test host app without UIScene adoption. CI is pinned to an older Xcode so it is unaffected for now. Not changed here.Manual: on a device, switch from an identified user on A to B and re-identify from the callback. The result should be
.switchedCleanly, with nodid not start cleanlyerror, and in-apps should load for B aftersetEmail.🧾 Changelog
Updated under
[Unreleased]. The warning-cause list in theswitchProjectentry gains the real fifth cause, says that nobody identified yet on the new project is not a warning, explains the expectedBoth email and userId are nillog line, and notes that a simulator has no APNs token. A new Fixed entry covers this change. The pre-init Added bullet, left stale by SDK-758, and the SDK-758 Fixed entry now describe the actual behaviour.📹 Loom recording if applicable
Not recorded.
🐞 Github Issues solved
None.
📚 Docs PR if applicable
switchProjectdocs are tracked in SDK-676. The result contract described there should match the corrected CHANGELOG wording.