Skip to content

Commit

Permalink
AND-8882 Updated stakekit errors (#3616)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sateetas authored Oct 28, 2024
1 parent 94ef7fd commit 5d456b5
Show file tree
Hide file tree
Showing 18 changed files with 275 additions and 589 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ sealed class AnalyticsParam {
const val ERROR_CODE = "Error Code"
const val ERROR_KEY = "Error Key"
const val ERROR_TYPE = "Error Type"
const val ERROR_MESSAGE = "Error Message"
const val CREATION_TYPE = "Creation type"
const val DAPP_NAME = "DApp Name"
const val DAPP_URL = "DApp Url"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.tangem.core.analytics.di

import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.api.ParamsInterceptorHolder
import com.tangem.core.analytics.filter.OneTimeEventFilter
import com.tangem.domain.analytics.repository.AnalyticsRepository
import dagger.Module
Expand All @@ -20,6 +21,12 @@ internal object AnalyticsModule {
return Analytics // todo replace after refactoring calling Analytics in whole project
}

@Singleton
@Provides
fun provideParamsInterceptorHolder(): ParamsInterceptorHolder {
return Analytics // todo replace after refactoring calling Analytics in whole project
}

@Provides
fun provideOneTimeEventFilter(analyticsRepository: AnalyticsRepository): OneTimeEventFilter {
return OneTimeEventFilter(analyticsRepository)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO.RewardT
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO.ValidatorDTO.ValidatorStatusDTO
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionStatusDTO
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionTypeDTO
import com.tangem.datasource.api.stakekit.models.response.model.error.AccessDeniedErrorTypeDTO
import com.tangem.datasource.api.stakekit.models.response.model.error.StakeKitErrorMessageDTO
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionStatusDTO
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionTypeDTO

Expand Down Expand Up @@ -40,9 +38,6 @@ fun Moshi.Builder.addStakeKitEnumFallbackAdapters(): Moshi.Builder {
StakingTransactionStatusDTO::class.java to StakingTransactionStatusDTO.UNKNOWN,
StakingTransactionTypeDTO::class.java to StakingTransactionTypeDTO.UNKNOWN,
ValidatorStatusDTO::class.java to ValidatorStatusDTO.UNKNOWN,
// error enums
AccessDeniedErrorTypeDTO::class.java to AccessDeniedErrorTypeDTO.UNKNOWN,
StakeKitErrorMessageDTO::class.java to StakeKitErrorMessageDTO.UNKNOWN,
)

return apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ package com.tangem.datasource.api.stakekit.models.response.model.error
import com.squareup.moshi.Json

class StakeKitErrorResponse(
@Json(name = "message")
val message: String? = null,
@Json(name = "code")
val code: Int? = null,
@Json(name = "path")
val path: String? = null,

@Json(name = "details")
val details: StakeKitErrorDetailsDTO? = null,
@Json(name = "message")
val message: StakeKitErrorMessageDTO? = null,
@Json(name = "level")
val level: String? = null, // unused

// 403
@Json(name = "type")
val type: AccessDeniedErrorTypeDTO? = null,
@Json(name = "code")
val code: String? = null,
val type: String? = null,
@Json(name = "countryCode")
val countryCode: String?,
@Json(name = "regionCode")
Expand All @@ -31,134 +34,3 @@ data class StakeKitErrorDetailsDTO(
@Json(name = "yieldId")
val yieldId: String? = null,
)

enum class AccessDeniedErrorTypeDTO {
@Json(name = "GEO_LOCATION")
GEO_LOCATION,

UNKNOWN,
}

enum class StakeKitErrorMessageDTO {
@Json(name = "MissingArgumentsError")
MISSING_ARGUMENTS_ERROR,

@Json(name = "MinimumAmountNotReached")
MINIMUM_AMOUNT_NOT_REACHED,

@Json(name = "YieldUnderMaintenanceError")
YIELD_UNDER_MAINTENANCE_ERROR,

@Json(name = "InsufficientFundsError")
INSUFFICIENT_FUNDS_ERROR,

@Json(name = "StakedPositionNotFoundError")
STAKED_POSITION_NOT_FOUND_ERROR,

@Json(name = "InvalidAmountSubmittedError")
INVALID_AMOUNT_SUBMITTED_ERROR,

@Json(name = "BalanceUnavailableError")
BALANCE_UNAVAILABLE_ERROR,

@Json(name = "GasPriceUnavailableError")
GAS_PRICE_UNAVAILABLE_ERROR,

@Json(name = "NotImplementedError")
NOT_IMPLEMENTED_ERROR,

@Json(name = "TokenNotFoundError")
TOKEN_NOT_FOUND_ERROR,

@Json(name = "BroadcastTransactionError")
BROADCAST_TRANSACTION_ERROR,

@Json(name = "MissingGasPriceStrategyError")
MISSING_GAS_PRICE_STRATEGY_ERROR,

@Json(name = "SubstrateMalformedTransactionHashError")
SUBSTRATE_MALFORMED_TRANSACTION_HASH_ERROR,

@Json(name = "TronMaximumAmountOfValidatorsExceededError")
TRON_MAXIMUM_AMOUNT_OF_VALIDATORS_EXCEEDED_ERROR,

@Json(name = "SubstratePoolNotFoundError")
SUBSTRATE_POOL_NOT_FOUND_ERROR,

@Json(name = "SubstrateBondedAmountTooLowError")
SUBSTRATE_BONDED_AMOUNT_TOO_LOW_ERROR,

@Json(name = "TronMissingResourceTypeArgumentError")
TRON_MISSING_RESOURCE_TYPE_ARGUMENT_ERROR,

@Json(name = "AaveV3PoolFrozenError")
AAVE_V3_POOL_FROZEN_ERROR,

@Json(name = "AaveV3TokenPairNotFoundError")
AAVE_V3_TOKEN_PAIR_NOT_FOUND_ERROR,

@Json(name = "YearnVaultAtMaxCapacityError")
YEARN_VAULT_AT_MAX_CAPACITY_ERROR,

@Json(name = "StETHNoWithdrawalRequestsFoundError")
STETH_NO_WITHDRAWAL_REQUESTS_FOUND_ERROR,

@Json(name = "MorphoLendingPoolPausedError")
MORPHO_LENDING_POOL_PAUSED_ERROR,

@Json(name = "NonceUnavailableError")
NONCE_UNAVAILABLE_ERROR,

@Json(name = "CosmosAcccountNotFoundError")
COSMOS_ACCOUNT_NOT_FOUND_ERROR,

@Json(name = "AvalancheMissingAdditionalAddressesArgumentError")
AVALANCHE_MISSING_ADDITIONAL_ADDRESSES_ARGUMENT_ERROR,

@Json(name = "AvalancheValidatorInfoNotFoundError")
AVALANCHE_VALIDATOR_INFO_NOT_FOUND_ERROR,

@Json(name = "SolanaTransactionSignatureVerificationFailureError")
SOLANA_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE_ERROR,

@Json(name = "SolanaUnableTocreateStakeAccountError")
SOLANA_UNABLE_TO_CREATE_STAKE_ACCOUNT_ERROR,

@Json(name = "SolanaStakeAmountTooLowError")
SOLANA_STAKE_AMOUNT_TOO_LOW_ERROR,

@Json(name = "SolanaUnstakeAmountTooLowError")
SOLANA_UNSTAKE_AMOUNT_TOO_LOW_ERROR,

@Json(name = "SolanaStakeAccountsNotFoundError")
SOLANA_STAKE_ACCOUNTS_NOT_FOUND_ERROR,

@Json(name = "SolanaEligibleStakeAccountsNotFoundError")
SOLANA_ELIGIBLE_STAKE_ACCOUNTS_NOT_FOUND_ERROR,

@Json(name = "TezosNoBalanceDelegatedError")
TEZOS_NO_BALANCE_DELEGATED_ERROR,

@Json(name = "TezosMissingPubkeyArgumentError")
TEZOS_MISSING_PUBKEY_ARGUMENT_ERROR,

@Json(name = "TezosEstimateRevealGasLimitError")
TEZOS_ESTIMATE_REVEAL_GAS_LIMIT_ERROR,

@Json(name = "TezosBalanceAlreadyDelegatedError")
TEZOS_BALANCE_ALREADY_DELEGATED_ERROR,

@Json(name = "BinanceAccountNotFoundError")
BINANCE_ACCOUNT_NOT_FOUND_ERROR,

@Json(name = "BinanceMissingAccountNumberOrSequenceError")
BINANCE_MISSING_ACCOUNT_NUMBER_OR_SEQUENCE_ERROR,

@Json(name = "GRTStakingDisabledError")
GRT_STAKING_DISABLED_ERROR,

@Json(name = "GRTStakingDisabledLedgerLiveError")
GRT_STAKING_DISABLED_LEDGER_LIVE_ERROR,

UNKNOWN,
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
package com.tangem.data.staking

import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.data.staking.converters.error.StakeKitErrorConverter
import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.domain.staking.analytics.StakingAnalyticsEvent
import com.tangem.domain.staking.model.stakekit.StakingError
import com.tangem.domain.staking.repositories.StakingErrorResolver

internal class DefaultStakingErrorResolver(
private val analyticsEventHandler: AnalyticsEventHandler,
private val stakeKitErrorConverter: StakeKitErrorConverter,
) : StakingErrorResolver {

override fun resolve(throwable: Throwable): StakingError {
return if (throwable is ApiResponseError.HttpException) {
val error = if (throwable is ApiResponseError.HttpException) {
stakeKitErrorConverter.convert(throwable.errorBody.orEmpty())
} else {
StakingError.UnknownError()
StakingError.DomainError(throwable.message)
}

when (error) {
is StakingError.StakeKitApiError -> {
analyticsEventHandler.send(StakingAnalyticsEvent.StakeKitApiError(error))
}
is StakingError.StakeKitUnknownError -> {
analyticsEventHandler.send(StakingAnalyticsEvent.StakeKitApiUnknownError(error))
}
else -> {
// intentionally do nothing
}
}

return error
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.tangem.data.staking.converters.error

import com.squareup.moshi.JsonAdapter
import com.tangem.datasource.api.stakekit.models.response.model.error.AccessDeniedErrorTypeDTO
import com.tangem.datasource.api.stakekit.models.response.model.error.StakeKitErrorMessageDTO
import com.tangem.datasource.api.stakekit.models.response.model.error.StakeKitErrorResponse
import com.tangem.domain.staking.model.stakekit.StakingError
import com.tangem.utils.converter.Converter
Expand All @@ -11,105 +9,18 @@ internal class StakeKitErrorConverter(
private val jsonAdapter: JsonAdapter<StakeKitErrorResponse>,
) : Converter<String, StakingError> {

@Suppress("CyclomaticComplexMethod", "LongMethod")
override fun convert(value: String): StakingError {
return try {
val stakeKitErrorResponse = jsonAdapter.fromJson(value) ?: return StakingError.UnknownError(value)
val stakeKitErrorResponse = jsonAdapter.fromJson(value)
?: return StakingError.StakeKitUnknownError(value)

if (stakeKitErrorResponse.type == AccessDeniedErrorTypeDTO.GEO_LOCATION) {
StakingError.UnavailableDueToGeolocationError(
tags = stakeKitErrorResponse.tags ?: emptyList(),
)
}

when (stakeKitErrorResponse.message) {
StakeKitErrorMessageDTO.MINIMUM_AMOUNT_NOT_REACHED -> StakingError.MinimumAmountNotReachedError(
amount = stakeKitErrorResponse.details?.amount ?: "",
)
StakeKitErrorMessageDTO.MISSING_ARGUMENTS_ERROR -> StakingError.MissingArgumentsError(
arguments = stakeKitErrorResponse.details?.arguments ?: "",
)
StakeKitErrorMessageDTO.YIELD_UNDER_MAINTENANCE_ERROR -> StakingError.YieldUnderMaintenanceError(
yieldId = stakeKitErrorResponse.details?.yieldId ?: "",
)
StakeKitErrorMessageDTO.INSUFFICIENT_FUNDS_ERROR ->
StakingError.InsufficientFundsError
StakeKitErrorMessageDTO.STAKED_POSITION_NOT_FOUND_ERROR ->
StakingError.StakedPositionNotFoundError
StakeKitErrorMessageDTO.INVALID_AMOUNT_SUBMITTED_ERROR ->
StakingError.InvalidAmountSubmittedError
StakeKitErrorMessageDTO.BALANCE_UNAVAILABLE_ERROR ->
StakingError.BalanceUnavailableError
StakeKitErrorMessageDTO.GAS_PRICE_UNAVAILABLE_ERROR ->
StakingError.GasPriceUnavailableError
StakeKitErrorMessageDTO.NOT_IMPLEMENTED_ERROR ->
StakingError.NotImplementedError
StakeKitErrorMessageDTO.TOKEN_NOT_FOUND_ERROR ->
StakingError.TokenNotFoundError
StakeKitErrorMessageDTO.BROADCAST_TRANSACTION_ERROR ->
StakingError.BroadcastTransactionError
StakeKitErrorMessageDTO.MISSING_GAS_PRICE_STRATEGY_ERROR ->
StakingError.MissingGasPriceStrategyError
StakeKitErrorMessageDTO.SUBSTRATE_MALFORMED_TRANSACTION_HASH_ERROR ->
StakingError.SubstrateMalformedTransactionHashError
StakeKitErrorMessageDTO.TRON_MAXIMUM_AMOUNT_OF_VALIDATORS_EXCEEDED_ERROR ->
StakingError.TronMaximumAmountOfValidatorsExceededError
StakeKitErrorMessageDTO.SUBSTRATE_POOL_NOT_FOUND_ERROR ->
StakingError.SubstratePoolNotFoundError
StakeKitErrorMessageDTO.SUBSTRATE_BONDED_AMOUNT_TOO_LOW_ERROR ->
StakingError.SubstrateBondedAmountTooLowError
StakeKitErrorMessageDTO.TRON_MISSING_RESOURCE_TYPE_ARGUMENT_ERROR ->
StakingError.TronMissingResourceTypeArgumentError
StakeKitErrorMessageDTO.AAVE_V3_POOL_FROZEN_ERROR ->
StakingError.AaveV3PoolFrozenError
StakeKitErrorMessageDTO.AAVE_V3_TOKEN_PAIR_NOT_FOUND_ERROR ->
StakingError.AaveV3TokenPairNotFoundError
StakeKitErrorMessageDTO.YEARN_VAULT_AT_MAX_CAPACITY_ERROR ->
StakingError.YearnVaultAtMaxCapacityError
StakeKitErrorMessageDTO.STETH_NO_WITHDRAWAL_REQUESTS_FOUND_ERROR ->
StakingError.StETHNoWithdrawalRequestsFoundError
StakeKitErrorMessageDTO.MORPHO_LENDING_POOL_PAUSED_ERROR ->
StakingError.MorphoLendingPoolPausedError
StakeKitErrorMessageDTO.NONCE_UNAVAILABLE_ERROR ->
StakingError.NonceUnavailableError
StakeKitErrorMessageDTO.COSMOS_ACCOUNT_NOT_FOUND_ERROR ->
StakingError.CosmosAcccountNotFoundError
StakeKitErrorMessageDTO.AVALANCHE_MISSING_ADDITIONAL_ADDRESSES_ARGUMENT_ERROR ->
StakingError.AvalancheMissingAdditionalAddressesArgumentError
StakeKitErrorMessageDTO.AVALANCHE_VALIDATOR_INFO_NOT_FOUND_ERROR ->
StakingError.AvalancheValidatorInfoNotFoundError
StakeKitErrorMessageDTO.SOLANA_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE_ERROR ->
StakingError.SolanaTransactionSignatureVerificationFailureError
StakeKitErrorMessageDTO.SOLANA_UNABLE_TO_CREATE_STAKE_ACCOUNT_ERROR ->
StakingError.SolanaUnableTocreateStakeAccountError
StakeKitErrorMessageDTO.SOLANA_STAKE_AMOUNT_TOO_LOW_ERROR ->
StakingError.SolanaStakeAmountTooLowError
StakeKitErrorMessageDTO.SOLANA_UNSTAKE_AMOUNT_TOO_LOW_ERROR ->
StakingError.SolanaUnstakeAmountTooLowError
StakeKitErrorMessageDTO.SOLANA_STAKE_ACCOUNTS_NOT_FOUND_ERROR ->
StakingError.SolanaStakeAccountsNotFoundError
StakeKitErrorMessageDTO.SOLANA_ELIGIBLE_STAKE_ACCOUNTS_NOT_FOUND_ERROR ->
StakingError.SolanaEligibleStakeAccountsNotFoundError
StakeKitErrorMessageDTO.TEZOS_NO_BALANCE_DELEGATED_ERROR ->
StakingError.TezosNoBalanceDelegatedError
StakeKitErrorMessageDTO.TEZOS_MISSING_PUBKEY_ARGUMENT_ERROR ->
StakingError.TezosMissingPubkeyArgumentError
StakeKitErrorMessageDTO.TEZOS_ESTIMATE_REVEAL_GAS_LIMIT_ERROR ->
StakingError.TezosEstimateRevealGasLimitError
StakeKitErrorMessageDTO.TEZOS_BALANCE_ALREADY_DELEGATED_ERROR ->
StakingError.TezosBalanceAlreadyDelegatedError
StakeKitErrorMessageDTO.BINANCE_ACCOUNT_NOT_FOUND_ERROR ->
StakingError.BinanceAccountNotFoundError
StakeKitErrorMessageDTO.BINANCE_MISSING_ACCOUNT_NUMBER_OR_SEQUENCE_ERROR ->
StakingError.BinanceMissingAccountNumberOrSequenceError
StakeKitErrorMessageDTO.GRT_STAKING_DISABLED_ERROR ->
StakingError.GRTStakingDisabledError
StakeKitErrorMessageDTO.GRT_STAKING_DISABLED_LEDGER_LIVE_ERROR ->
StakingError.GRTStakingDisabledLedgerLiveError
else -> StakingError.UnknownError(value)
}
return StakingError.StakeKitApiError(
message = stakeKitErrorResponse.message,
code = stakeKitErrorResponse.code,
methodName = stakeKitErrorResponse.path,
)
} catch (e: Exception) {
StakingError.UnknownError(value)
StakingError.StakeKitUnknownError(value)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tangem.data.staking.di

import com.squareup.moshi.Moshi
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.staking.DefaultStakingErrorResolver
import com.tangem.data.staking.DefaultStakingPendingTransactionRepository
Expand Down Expand Up @@ -79,10 +80,14 @@ internal object StakingDataModule {

@Provides
@Singleton
internal fun provideStakingErrorResolver(@NetworkMoshi moshi: Moshi): StakingErrorResolver {
internal fun provideStakingErrorResolver(
@NetworkMoshi moshi: Moshi,
analyticsEventHandler: AnalyticsEventHandler,
): StakingErrorResolver {
val jsonAdapter = moshi.adapter(StakeKitErrorResponse::class.java)
return DefaultStakingErrorResolver(
stakeKitErrorConverter = StakeKitErrorConverter(jsonAdapter),
analyticsEventHandler = analyticsEventHandler,
)
}
}
Loading

0 comments on commit 5d456b5

Please sign in to comment.