Skip to content

SDKS-5184: Update sample app to showcase JSON config#212

Merged
spetrov merged 3 commits into
developfrom
SDKS-5184
Jun 23, 2026
Merged

SDKS-5184: Update sample app to showcase JSON config#212
spetrov merged 3 commits into
developfrom
SDKS-5184

Conversation

@vibhorgoswami

@vibhorgoswami vibhorgoswami commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

JIRA Ticket

SDKS-5184

Description

This PR provides an option to load json files of configuration.
image

Summary by CodeRabbit

  • New Features
    • Added three new sample OIDC configuration files (DaVinci, Journey, and OpenID) with configurable timeouts, logging, and additional authentication parameters.
  • Refactor
    • Improved configuration preset loading by auto-discovering bundled JSON assets and using safer JSON-based persistence and application of presets.
    • Updated environment preset state initialization to be more predictable and only activate SDK setup when required identifiers are present.
  • Bug Fixes
    • Standardized Device Auth user-info endpoint naming across the UI and saved configuration.
    • Added stronger error handling for token and user-info requests to prevent crashes and clear stale results on failure.

@vibhorgoswami vibhorgoswami requested a review from spetrov June 19, 2026 22:59
@vibhorgoswami vibhorgoswami self-assigned this Jun 19, 2026
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0e57e150-46f4-4ee7-99fb-25755c691f9d

📥 Commits

Reviewing files that changed from the base of the PR and between d8e0428 and 5952488.

📒 Files selected for processing (3)
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt

📝 Walkthrough

Walkthrough

Three new JSON asset configuration files (Journey, DaVinci, OpenID) are added to the sample app's assets directory. EnvViewModel is updated to scan and parse these asset files at init time via a new loadAssetConfigs() function, converting preset lists to Compose state-backed vars and prepending asset-derived results. All JSON serialization/deserialization is migrated from org.json to kotlinx.serialization. Device Auth configuration fields are standardized to use userInfoEndpoint naming. Config loading is refactored to require explicit clientIds instead of falling back to defaults. TokenViewModel and UserProfileViewModel are hardened with try/catch exception handling around token and user-info operations.

Changes

Configuration Presets, Asset Loading, and JSON Migration

Layer / File(s) Summary
New JSON asset config files
samples/pingsampleapp/src/main/assets/DaVinciJsonConfig.json, samples/pingsampleapp/src/main/assets/journeyJsonConfig.json, samples/pingsampleapp/src/main/assets/openIdJsonConfig.json
Adds three asset config files covering DaVinci (OIDC-only), Journey (journey + OIDC), and OpenID (OIDC + explicit endpoints) flows, each with timeout, log level, and full connection/auth parameters.
Asset loader: imports, AssetConfigs, and loadAssetConfigs()
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
Removes org.json imports and adds kotlinx.serialization.json utilities. Introduces AssetConfigType enum, AssetConfigs data class, and loadAssetConfigs() function that enumerates assets/*.json, parses with Json.parseToJsonElement(), infers config type from JSON keys (journey key, nested oidc.openId structure, or DaVinci/Web), and groups results into typed preset lists while silently ignoring per-file parse errors.
Preset list Compose state backing and init loading
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
Converts package-level redirect URIs from lateinit to Uri.EMPTY initialized vars. Public preset lists become mutableStateOf vars with private set. During init, loadAssetConfigs() runs on IO dispatcher; results are assigned to state lists on Main dispatcher. SDK instances are built only when applied configs are non-null.
Device Auth userInfoEndpoint field standardization
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt, samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/Env.kt
Renames Device Auth fields from userinfoEndpoint to userInfoEndpoint in DeviceAuthConfigState, SDK client building (JsonConfigKey.USER_INFO_ENDPOINT), DataStore key mapping (da_userInfoEndpoint), persistence/readback, and UI field wiring in DeviceAuthSheetContent.
Config loading refactor: nullable applied configs
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
Refactored initConfigs() to build SDK instances only when stored *_clientId is present; builders return null when clientId is absent. Applied config loaders now return nullable states and read the corrected userInfoEndpoint DataStore key. Delete fallback uses preset.firstOrNull() and clears state if no preset exists.
DataStore custom-config JSON serialization migration
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
Custom-config save/load for journey, OIDC, and device-auth is rewritten from org.json to kotlinx.serialization (buildJsonArray/buildJsonObject for serialization; Json.parseToJsonElement().jsonArray.map for deserialization). Parse failures return emptyList() via runCatching.getOrDefault().

Token and UserInfo Exception Handling

Layer / File(s) Summary
TokenViewModel: try/catch around token/revoke/refresh
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt
All token operation helpers (Journey, DaVinci, OIDC, Auth Grant) wrap token calls in try/catch. Access-token and refresh-token operations preserve Failure/Success result handling but catch unexpected exceptions and clear token/error fields to null. Revoke operations catch and ignore exceptions while still clearing state. Missing-client branches are simplified to direct state.update calls.
UserProfileViewModel: try/catch around userInfo operations
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt
Journey, DaVinci, OIDC, and Auth Grant *UserInfo methods wrap user retrieval and userinfo(false) calls in try/catch. On thrown exceptions, both user and error fields are cleared to null instead of propagating.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ForgeRock/ping-android-sdk#181: Both PRs heavily modify EnvViewModel and the initConfigs() startup/config-loading flow, replacing hardcoded/preset handling with DataStore/app-driven OIDC/Journey/DaVinci config application.
  • ForgeRock/ping-android-sdk#202: Both PRs update TokenViewModel and UserProfileViewModel to handle auth-grant token/user-info operations, with exception-handling hardening added in the main PR alongside the Device Authorization flow changes.

Suggested reviewers

  • spetrov
  • vahancouver
  • witrisna

Poem

🐇 Hopping through assets with config delight,
Three JSON files planted, each perfectly right.
I swapped out org.json for kotlinx with glee,
Now presets load from files, smooth as can be.
Exception handlers catch what might slip through—
A rabbit's refactor, robust and true! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: updating the sample app to showcase JSON configuration functionality, which is directly supported by the addition of three JSON config files and related code changes in EnvViewModel.
Description check ✅ Passed The description includes both required sections from the template (JIRA Ticket with proper link and Description with brief explanation), though the description text is minimal and an image is included for context.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SDKS-5184

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 detekt (1.23.8)
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt

Exception in thread "main" com.beust.jcommander.ParameterException: Provided path 'detekt-config.yaml' does not exist!
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:16)
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:11)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert$lambda$1(ArgumentConverters.kt:31)
at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:210)
at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:815)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert(ArgumentConverters.kt:32)
at io.gitlab.arturbosch.detekt.cli.MultipleExistingPathConverter.convert(ArgumentConverters.kt:41)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15$lambda$6(Spec.kt:46)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilder.config(ProcessingSpecBuilder.kt:32)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15(Spec.kt:41)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilderKt.processingSpec(ProcessingSpecBuilder.kt:15)
at io.github.detekt.tooling.api.spec.ProcessingSpec$Companion.invoke(ProcessingSpec.kt:23)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec(Spec.kt:9)
at io.gitlab.arturbosch.detekt.cli.runners.Runner.(Runner.kt:20)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:31)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:14)
at io.gitlab.arturbosch.detekt.cli.Main.main(Main.kt:20)

samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt

Exception in thread "main" com.beust.jcommander.ParameterException: Provided path 'detekt-config.yaml' does not exist!
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:16)
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:11)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert$lambda$1(ArgumentConverters.kt:31)
at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:210)
at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:815)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert(ArgumentConverters.kt:32)
at io.gitlab.arturbosch.detekt.cli.MultipleExistingPathConverter.convert(ArgumentConverters.kt:41)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15$lambda$6(Spec.kt:46)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilder.config(ProcessingSpecBuilder.kt:32)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15(Spec.kt:41)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilderKt.processingSpec(ProcessingSpecBuilder.kt:15)
at io.github.detekt.tooling.api.spec.ProcessingSpec$Companion.invoke(ProcessingSpec.kt:23)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec(Spec.kt:9)
at io.gitlab.arturbosch.detekt.cli.runners.Runner.(Runner.kt:20)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:31)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:14)
at io.gitlab.arturbosch.detekt.cli.Main.main(Main.kt:20)

samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt

Exception in thread "main" com.beust.jcommander.ParameterException: Provided path 'detekt-config.yaml' does not exist!
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:16)
at io.gitlab.arturbosch.detekt.cli.ExistingPathConverter.convert(ArgumentConverters.kt:11)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert$lambda$1(ArgumentConverters.kt:31)
at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:210)
at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:815)
at io.gitlab.arturbosch.detekt.cli.DetektInputPathConverter$DefaultImpls.convert(ArgumentConverters.kt:32)
at io.gitlab.arturbosch.detekt.cli.MultipleExistingPathConverter.convert(ArgumentConverters.kt:41)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15$lambda$6(Spec.kt:46)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilder.config(ProcessingSpecBuilder.kt:32)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec$lambda$15(Spec.kt:41)
at io.github.detekt.tooling.dsl.ProcessingSpecBuilderKt.processingSpec(ProcessingSpecBuilder.kt:15)
at io.github.detekt.tooling.api.spec.ProcessingSpec$Companion.invoke(ProcessingSpec.kt:23)
at io.gitlab.arturbosch.detekt.cli.SpecKt.createSpec(Spec.kt:9)
at io.gitlab.arturbosch.detekt.cli.runners.Runner.(Runner.kt:20)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:31)
at io.gitlab.arturbosch.detekt.cli.CliRunner.run(CliRunner.kt:14)
at io.gitlab.arturbosch.detekt.cli.Main.main(Main.kt:20)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt`:
- Around line 183-186: The userinfoEndpoint field is being parsed with an
incorrect JSON key name that has a capital I in "userInfoEndpoint", but the
actual key in the openIdJsonConfig.json file uses lowercase i as
"userinfoEndpoint". Change the JSON key parameter in the line assigning
userinfoEndpoint from "userInfoEndpoint" to "userinfoEndpoint" to match the
actual configuration file key and ensure the value is correctly populated
instead of defaulting to an empty string.
- Around line 135-137: The loadAssetConfigs() method opens file streams via
context.assets.open(fileName).bufferedReader() without closing them, causing
resource leaks in the loop. Wrap the bufferedReader().readText() call with the
Kotlin .use { } function to ensure the stream is automatically closed after
reading, preventing file descriptor leaks on each iteration of the loop.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4eb46e48-cd4a-4f03-9ff2-1f5dd43e1cba

📥 Commits

Reviewing files that changed from the base of the PR and between ed0f5d6 and 9cb0cc0.

📒 Files selected for processing (4)
  • samples/pingsampleapp/src/main/assets/DaVinciJsonConfig.json
  • samples/pingsampleapp/src/main/assets/journeyJsonConfig.json
  • samples/pingsampleapp/src/main/assets/openIdJsonConfig.json
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt

Comment on lines +183 to +186
authorizationEndpoint = openIdObj?.str("authorizationEndpoint") ?: "",
tokenEndpoint = openIdObj?.str("tokenEndpoint") ?: "",
userinfoEndpoint = openIdObj?.str("userInfoEndpoint") ?: "",
endSessionEndpoint = openIdObj?.str("endSessionEndpoint") ?: "",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Device-auth userinfoEndpoint is parsed with the wrong JSON key.

openIdJsonConfig.json uses userinfoEndpoint, but this parser reads userInfoEndpoint (capital I), so the value is always empty and the loaded device-auth preset is incomplete.

Suggested fix
-                    userinfoEndpoint = openIdObj?.str("userInfoEndpoint") ?: "",
+                    userinfoEndpoint = openIdObj?.str("userinfoEndpoint") ?: "",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt`
around lines 183 - 186, The userinfoEndpoint field is being parsed with an
incorrect JSON key name that has a capital I in "userInfoEndpoint", but the
actual key in the openIdJsonConfig.json file uses lowercase i as
"userinfoEndpoint". Change the JSON key parameter in the line assigning
userinfoEndpoint from "userInfoEndpoint" to "userinfoEndpoint" to match the
actual configuration file key and ensure the value is correctly populated
instead of defaulting to an empty string.

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 44.14%. Comparing base (ed0f5d6) to head (5952488).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #212      +/-   ##
=============================================
+ Coverage      44.12%   44.14%   +0.02%     
  Complexity      1393     1393              
=============================================
  Files            316      316              
  Lines           9756     9756              
  Branches        1495     1495              
=============================================
+ Hits            4305     4307       +2     
  Misses          4887     4887              
+ Partials         564      562       -2     
Flag Coverage Δ
integration-tests 28.27% <ø> (+0.01%) ⬆️
unit-tests 26.04% <ø> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt`:
- Around line 198-204: The web.add() method call with OidcConfigState parameters
(containing clientId, discoveryEndpoint, scopes, redirectUri, and display
fields) is executing unconditionally after the when block, causing config
entries to be added to multiple lists when they should only appear in one.
Delete this entire web.add() block (lines 198-204) so that each config type is
only added to its appropriate list as determined by the when expression.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 80b5a3ad-dea8-4d15-9a67-093a168e1705

📥 Commits

Reviewing files that changed from the base of the PR and between 9cb0cc0 and 9d88869.

📒 Files selected for processing (5)
  • samples/pingsampleapp/src/main/assets/DaVinciJsonConfig.json
  • samples/pingsampleapp/src/main/assets/journeyJsonConfig.json
  • samples/pingsampleapp/src/main/assets/openIdJsonConfig.json
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/Env.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • samples/pingsampleapp/src/main/assets/DaVinciJsonConfig.json
  • samples/pingsampleapp/src/main/assets/journeyJsonConfig.json
  • samples/pingsampleapp/src/main/assets/openIdJsonConfig.json

@spetrov spetrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@vibhorgoswami vibhorgoswami marked this pull request as ready for review June 22, 2026 18:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt (1)

477-480: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Consider moving SDK instance builds off Main dispatcher.

The SDK instance builders (buildJourneyInstance, etc.) execute on Dispatchers.Main after the context switch. If these perform any blocking I/O (secure storage reads, network setup), this could cause UI jank on app launch.

For a sample app this may be acceptable, but production code should consider:

  1. Building instances on IO dispatcher
  2. Using a loading state to defer UI interaction until ready
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt`
around lines 477 - 480, Move the SDK instance builder calls
(buildJourneyInstance, buildDaVinciInstance, buildWebInstance,
buildDeviceAuthInstance) off the Main dispatcher to prevent blocking UI
operations. Use Dispatchers.IO for these blocking I/O operations by wrapping the
builder calls in a withContext(Dispatchers.IO) block. Consider implementing a
loading state variable that is set to true before starting the builders and
false after completion, allowing the UI to defer interactions until all SDK
instances are fully initialized.
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt (1)

122-124: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider logging exceptions before discarding them.

All catch blocks silently clear state without any logging, making it difficult to diagnose unexpected failures during development. The user sees a generic "No token information available" message with no way to distinguish between "no session exists" and "an unexpected error occurred."

Adding a log statement would aid debugging while preserving the graceful degradation behavior:

             } catch (e: Exception) {
+                Log.w("TokenViewModel", "Unexpected error during token operation", e)
                 state.update { it.copy(journeyToken = null, journeyError = null) }
             }

Also applies to: 152-154, 172-174, 202-204, 222-224, 252-254, 272-274, 302-304

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt`
around lines 122 - 124, In the TokenViewModel class, there are multiple catch
blocks that silently discard exceptions without logging them, making it
difficult to diagnose unexpected failures during development. Add a logging
statement to each catch block (lines 122-124, 152-154, 172-174, 202-204,
222-224, 252-254, 272-274, and 302-304) that logs the exception details before
the state.update call that clears the error state. This will preserve the
graceful degradation behavior while providing diagnostic information by
capturing the actual exception message and stack trace.
samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt (1)

114-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider logging exceptions before discarding them.

Same as TokenViewModel—exceptions are silently discarded, making unexpected failures invisible during development. Adding a log would help diagnose issues:

             } catch (e: Exception) {
+                Log.w("UserProfileViewModel", "Unexpected error fetching user info", e)
                 state.update { s -> s.copy(journeyUser = null, journeyError = null) }
             }

Also applies to: 139-141, 164-166, 189-191

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt`
around lines 114 - 116, The catch blocks in UserProfileViewModel are silently
discarding exceptions without logging them, making it difficult to diagnose
unexpected failures during development. Add logging statements in all the catch
blocks (the one shown in the diff and the additional ones at the other specified
locations) to log the exception details before updating the state. Use an
appropriate logger to record the exception with context about which operation
failed, so that unexpected errors are visible and debuggable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt`:
- Around line 477-480: Move the SDK instance builder calls
(buildJourneyInstance, buildDaVinciInstance, buildWebInstance,
buildDeviceAuthInstance) off the Main dispatcher to prevent blocking UI
operations. Use Dispatchers.IO for these blocking I/O operations by wrapping the
builder calls in a withContext(Dispatchers.IO) block. Consider implementing a
loading state variable that is set to true before starting the builders and
false after completion, allowing the UI to defer interactions until all SDK
instances are fully initialized.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt`:
- Around line 122-124: In the TokenViewModel class, there are multiple catch
blocks that silently discard exceptions without logging them, making it
difficult to diagnose unexpected failures during development. Add a logging
statement to each catch block (lines 122-124, 152-154, 172-174, 202-204,
222-224, 252-254, 272-274, and 302-304) that logs the exception details before
the state.update call that clears the error state. This will preserve the
graceful degradation behavior while providing diagnostic information by
capturing the actual exception message and stack trace.

In
`@samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt`:
- Around line 114-116: The catch blocks in UserProfileViewModel are silently
discarding exceptions without logging them, making it difficult to diagnose
unexpected failures during development. Add logging statements in all the catch
blocks (the one shown in the diff and the additional ones at the other specified
locations) to log the exception details before updating the state. Use an
appropriate logger to record the exception with context about which operation
failed, so that unexpected errors are visible and debuggable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e4ddf9e6-2a9a-4ad4-90c3-cc1af9ec8bf7

📥 Commits

Reviewing files that changed from the base of the PR and between 9d88869 and d8e0428.

📒 Files selected for processing (3)
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/config/EnvViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/token/TokenViewModel.kt
  • samples/pingsampleapp/src/main/java/com/pingidentity/samples/pingsampleapp/userprofile/UserProfileViewModel.kt

@spetrov spetrov merged commit c124db2 into develop Jun 23, 2026
36 of 38 checks passed
@spetrov spetrov deleted the SDKS-5184 branch June 23, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants