From a54fac24678e8e08d99e5341376d4d7752dca483 Mon Sep 17 00:00:00 2001 From: Nan Date: Fri, 15 Sep 2023 12:09:22 -0700 Subject: [PATCH] Differentiate login failure cases * The implementation of login with external_id has not changed * Add new ExecutionResult type of FAIL_CONFLICT to differentiate this case from general failure case of FAIL_NORETRY * Add logs for both type of responses, but still try to create the user on both failures (as before) --- .../core/internal/operations/IOperationExecutor.kt | 6 ++++++ .../core/internal/operations/impl/OperationRepo.kt | 1 + .../impl/executors/IdentityOperationExecutor.kt | 6 +++--- .../impl/executors/LoginUserOperationExecutor.kt | 11 +++++++++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/IOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/IOperationExecutor.kt index 8af45ce8a6..e27c49421e 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/IOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/IOperationExecutor.kt @@ -68,4 +68,10 @@ enum class ExecutionResult { * retried if authorization can be achieved. */ FAIL_UNAUTHORIZED, + + /** + * Used in special login case. + * The operation failed due to a conflict and can be handled. + */ + FAIL_CONFLICT, } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt index 91eaeb30c1..937fc037ea 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt @@ -167,6 +167,7 @@ internal class OperationRepo( } ExecutionResult.FAIL_UNAUTHORIZED, // TODO: Need to provide callback for app to reset JWT. For now, fail with no retry. ExecutionResult.FAIL_NORETRY, + ExecutionResult.FAIL_CONFLICT, -> { Logging.error("Operation execution failed without retry: $operations") // on failure we remove the operation from the store and wake any waiters diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt index 51818ea4f0..5d11f99fde 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt @@ -51,10 +51,10 @@ internal class IdentityOperationExecutor( return when (responseType) { NetworkUtils.ResponseStatusType.RETRYABLE -> ExecutionResponse(ExecutionResult.FAIL_RETRY) - NetworkUtils.ResponseStatusType.INVALID, - NetworkUtils.ResponseStatusType.CONFLICT, - -> + NetworkUtils.ResponseStatusType.INVALID -> ExecutionResponse(ExecutionResult.FAIL_NORETRY) + NetworkUtils.ResponseStatusType.CONFLICT -> + ExecutionResponse(ExecutionResult.FAIL_CONFLICT) NetworkUtils.ResponseStatusType.UNAUTHORIZED -> ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED) NetworkUtils.ResponseStatusType.MISSING -> { diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt index 8fd531da2b..849c880786 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt @@ -86,9 +86,16 @@ internal class LoginUserOperationExecutor( ExecutionResponse(ExecutionResult.SUCCESS_STARTING_ONLY, mapOf(loginUserOp.onesignalId to backendOneSignalId)) } + ExecutionResult.FAIL_CONFLICT -> { + // When the SetAliasOperation fails with conflict that *most likely* means the externalId provided + // is already associated to a user. This *expected* condition means we must create a user. + // We hardcode the response of "user-2" in the log to provide information to the SDK consumer + Logging.debug("LoginUserOperationExecutor now handling 409 response with \"code\": \"user-2\" by switching to user with \"external_id\": \"${loginUserOp.externalId}\"") + createUser(loginUserOp, operations) + } ExecutionResult.FAIL_NORETRY -> { - // When the SetAliasOperation fails without retry that *most likely* means the externalId provided - // is already associated to a user. This expected condition means we must create a user. + // Some other failure occurred, still try to recover by creating the user + Logging.error("LoginUserOperationExecutor encountered error. Attempt to recover by switching to user with \"external_id\": \"${loginUserOp.externalId}\"") createUser(loginUserOp, operations) } else -> ExecutionResponse(result.result)