Skip to content

Commit

Permalink
feat(analytics): add new api error type and segment error call for wh…
Browse files Browse the repository at this point in the history
…en user lands on oops errors from the order confirm screen
  • Loading branch information
blockdylanb committed May 2, 2022
1 parent ab031e9 commit 5e8d55f
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '@core/types'
import { createDeepEqualSelector } from '@core/utils'
import { selectors } from 'data'
import { PartialClientErrorProperties } from 'data/analytics/types/errors'
import { DEFAULT_BS_BALANCE } from 'data/components/buySell/model'
import { convertBaseToStandard } from 'data/components/exchange/services'
import { getOutputFromPair } from 'data/components/swap/model'
Expand All @@ -37,7 +38,7 @@ export const getCoinCustodialBalance = (
selectors.components.interest.getInterestAccountBalance
],
(
sbBalancesR: RemoteDataType<string, BSBalancesType>,
sbBalancesR: RemoteDataType<PartialClientErrorProperties, BSBalancesType>,
interestAccountBalanceR: RemoteDataType<string, InterestAccountBalanceType>
) => {
const sbCoinBalance = sbBalancesR.getOrElse({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,23 @@ type ErrorType =

type ErrorSource = 'CLIENT' | 'NABU' | 'UNKNOWN'

type ClientErrorAction = {
export type ClientErrorProperties = {
action?: string
error: ErrorType
network_endpoint?: string
network_error_code?: number
network_error_description?: string
network_error_id?: string
network_error_type?: ErrorType
source: ErrorSource
title: string
}

export type PartialClientErrorProperties = Partial<ClientErrorProperties>

export type ClientErrorAction = {
key: Events.CLIENT_ERROR
properties: {
action?: string
device: 'WEB'
error: ErrorType
network_endpoint: string
network_error_code?: number
network_error_description?: string
network_error_id?: string
network_error_type?: string
platform: 'WALLET'
source: ErrorSource
title: string
}
properties: ClientErrorProperties
}

export type TrackEventAction = ClientErrorAction
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type AnalyticsKey =
| TaxCenterEvents

const Analytics = {
...AccountRecoveryEvents,
...ClientErrorEvents,
...OnboardingAndVerificationEvents,
...ViewAndClickEvents,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { call, delay, put, retry, select, take } from 'redux-saga/effects'
import { Remote } from '@core'
import { APIType } from '@core/network/api'
import { BSPaymentMethodType, BSPaymentTypes, BSTransactionType } from '@core/types'
import { errorHandler } from '@core/utils'
import { errorCodeAndMessage, errorHandler } from '@core/utils'
import { actions, model, selectors } from 'data'
import { PartialClientErrorProperties } from 'data/analytics/types/errors'
import {
AddBankStepType,
BankDWStepType,
Expand Down Expand Up @@ -200,7 +201,14 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
yield put(A.setBankDetails({ account }))
}
} catch (e) {
const error = errorHandler(e)
const { code: network_error_code, message: network_error_description } =
errorCodeAndMessage(e)
const error: PartialClientErrorProperties = {
network_endpoint: '/payments/banktransfer',
network_error_code,
network_error_description,
source: 'NABU'
}
yield put(A.fetchBankTransferAccountsError(error))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'

import { Remote } from '@core'
import { CrossBorderLimits, CrossBorderLimitsPayload, WalletFiatType } from '@core/types'
import { PartialClientErrorProperties } from 'data/analytics/types/errors'
import { ModalNameType } from 'data/modals/types'
import { BankTransferAccountType } from 'data/types'

Expand Down Expand Up @@ -52,7 +53,10 @@ const brokerageSlice = createSlice({
state.bankCredentials = Remote.Loading
},
fetchBankTransferAccounts: () => {},
fetchBankTransferAccountsError: (state, action: PayloadAction<string>) => {
fetchBankTransferAccountsError: (
state,
action: PayloadAction<PartialClientErrorProperties>
) => {
state.bankTransferAccounts = Remote.Failure(action.payload)
},
fetchBankTransferAccountsLoading: (state) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import {
WalletFiatType,
WalletOptionsType
} from '@core/types'
import { errorHandler, errorHandlerCode } from '@core/utils'
import { errorCodeAndMessage, errorHandler, errorHandlerCode } from '@core/utils'
import { actions, selectors } from 'data'
import { ClientErrorProperties, PartialClientErrorProperties } from 'data/analytics/types/errors'
import { generateProvisionalPaymentAmount } from 'data/coins/utils'
import {
AddBankStepType,
Expand Down Expand Up @@ -882,13 +883,20 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
yield put(A.fetchSDDVerifiedSuccess(sddEligible))
}
} catch (e) {
// TODO: adding error handling with different error types and messages
const error = errorHandler(e)
const { code: network_error_code, message: network_error_description } =
errorCodeAndMessage(e)
const error: PartialClientErrorProperties = {
network_endpoint: '/sdd/verified',
network_error_code,
network_error_description,
source: 'NABU'
}
yield put(A.fetchSDDVerifiedFailure(error))
}
}

const fetchBSCards = function* ({ payload }: ReturnType<typeof A.fetchCards>) {
let useNewPaymentProviders = false
try {
yield call(waitForUserData)

Expand All @@ -900,15 +908,21 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
if (!loadCards) return yield put(A.fetchCardsSuccess([]))
if (!payload) yield put(A.fetchCardsLoading())

const useNewPaymentProviders = (yield select(
useNewPaymentProviders = (yield select(
selectors.core.walletOptions.getUseNewPaymentProviders
)).getOrElse(false)

const cards = yield call(api.getBSCards, useNewPaymentProviders)
yield put(A.fetchCardsSuccess(cards))
} catch (e) {
// TODO: adding error handling with different error types and messages
const error = errorHandler(e)
const { code: network_error_code, message: network_error_description } =
errorCodeAndMessage(e)
const error: PartialClientErrorProperties = {
network_endpoint: `/payments/cards?cardProvider=${useNewPaymentProviders}`,
network_error_code,
network_error_description,
source: 'NABU'
}
yield put(A.fetchCardsFailure(error))
}
}
Expand All @@ -935,23 +949,7 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
}
yield put(A.fetchFiatEligibleSuccess(fiatEligible))
} catch (e) {
// TODO: adding error handling with different error types and messages
const error = errorHandler(e)
yield put(
actions.analytics.trackEvent({
key: Analytics.CLIENT_ERROR,
properties: {
device: 'WEB',
error: 'OOPS_ERROR',
network_endpoint: '/simple-buy/eligible',
network_error_code: e.code,
network_error_description: error,
platform: 'WALLET',
source: 'NABU',
title: 'Oops! Something went wrong'
}
})
)
yield put(A.fetchFiatEligibleFailure(error))
}
}
Expand All @@ -975,24 +973,15 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
)
}
} catch (e) {
// TODO: adding error handling with different error types and messages
const error = errorHandler(e)
const { code: network_error_code, message: network_error_description } =
errorCodeAndMessage(e)
const error: PartialClientErrorProperties = {
network_endpoint: '/sdd/eligible',
network_error_code,
network_error_description,
source: 'NABU'
}
yield put(A.fetchSDDEligibleFailure(error))
yield put(
actions.analytics.trackEvent({
key: Analytics.CLIENT_ERROR,
properties: {
device: 'WEB',
error: 'OOPS_ERROR',
network_endpoint: '/sdd/eligible',
network_error_code: e.code,
network_error_description: error,
platform: 'WALLET',
source: 'NABU',
title: 'Oops! Something went wrong'
}
})
)
}
}

Expand All @@ -1012,12 +1001,10 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
actions.analytics.trackEvent({
key: Analytics.CLIENT_ERROR,
properties: {
device: 'WEB',
error: 'OOPS_ERROR',
network_endpoint: '/simple-buy/trades',
network_error_code: e.code,
network_error_description: error,
platform: 'WALLET',
source: 'NABU',
title: 'Oops! Something went wrong'
}
Expand Down Expand Up @@ -1046,12 +1033,11 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
actions.analytics.trackEvent({
key: Analytics.CLIENT_ERROR,
properties: {
device: 'WEB',
action: 'BUY',
error: 'OOPS_ERROR',
network_endpoint: '/simple-buy/pairs',
network_error_code: e.code,
network_error_description: error,
platform: 'WALLET',
source: 'NABU',
title: 'Oops! Something went wrong'
}
Expand Down Expand Up @@ -1184,23 +1170,15 @@ export default ({ api, coreSagas, networks }: { api: APIType; coreSagas: any; ne
const refresh = -moment().add(10, 'seconds').diff(quote.quoteExpiresAt)
yield delay(refresh)
} catch (e) {
const error = errorHandler(e)
const { code: network_error_code, message: network_error_description } =
errorCodeAndMessage(e)
const error: PartialClientErrorProperties = {
network_endpoint: '/brokerage/quote',
network_error_code,
network_error_description,
source: 'NABU'
}
yield put(A.fetchBuyQuoteFailure(error))
yield put(
actions.analytics.trackEvent({
key: Analytics.CLIENT_ERROR,
properties: {
device: 'WEB',
error: 'OOPS_ERROR',
network_endpoint: '/brokerage/quote',
network_error_code: e.code,
network_error_description: error,
platform: 'WALLET',
source: 'NABU',
title: 'Oops! Something went wrong'
}
})
)
// stop fetching new quote until user does retry action
yield put(A.stopPollBuyQuote())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
SwapUserLimitsType,
TradeAccumulatedItem
} from '@core/types'
import { PartialClientErrorProperties } from 'data/analytics/types/errors'
import {
BankTransferAccountType,
BSCardStateEnum,
Expand Down Expand Up @@ -220,7 +221,7 @@ const buySellSlice = createSlice({
state,
action: PayloadAction<{ currency?: CoinType; skipLoading?: boolean }>
) => {},
fetchBalanceFailure: (state, action: PayloadAction<string>) => {
fetchBalanceFailure: (state, action: PayloadAction<PartialClientErrorProperties>) => {
state.balances = Remote.Failure(action.payload)
},
fetchBalanceLoading: (state) => {
Expand All @@ -238,7 +239,7 @@ const buySellSlice = createSlice({
paymentMethodId?: BSCardType['id']
}>
) => {},
fetchBuyQuoteFailure: (state, action: PayloadAction<string>) => {
fetchBuyQuoteFailure: (state, action: PayloadAction<PartialClientErrorProperties>) => {
state.buyQuote = Remote.Failure(action.payload)
},
fetchBuyQuoteLoading: (state) => {
Expand All @@ -249,7 +250,7 @@ const buySellSlice = createSlice({
},
fetchCards: (state, action: PayloadAction<boolean>) => {},
// cards fetch fails so often in staging that this is a temp fix
fetchCardsFailure: (state, action: PayloadAction<string>) => {
fetchCardsFailure: (state, action: PayloadAction<PartialClientErrorProperties>) => {
state.cards = Remote.Success([])
},

Expand Down Expand Up @@ -365,7 +366,7 @@ const buySellSlice = createSlice({
state.quote = Remote.Success(action.payload)
},
fetchSDDEligibility: () => {},
fetchSDDEligibleFailure: (state, action: PayloadAction<string>) => {
fetchSDDEligibleFailure: (state, action: PayloadAction<PartialClientErrorProperties>) => {
state.sddEligible = Remote.Failure(action.payload)
},
fetchSDDEligibleLoading: (state) => {
Expand All @@ -375,7 +376,7 @@ const buySellSlice = createSlice({
state.sddEligible = Remote.Success(action.payload)
},
fetchSDDVerified: () => {},
fetchSDDVerifiedFailure: (state, action: PayloadAction<string>) => {
fetchSDDVerifiedFailure: (state, action: PayloadAction<PartialClientErrorProperties>) => {
state.sddVerified = Remote.Failure(action.payload)
},
fetchSDDVerifiedLoading: (state) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
SwapUserLimitsType,
TradeAccumulatedItem
} from '@core/types'
import { PartialClientErrorProperties } from 'data/analytics/types/errors'
import type { CountryType } from 'data/components/identityVerification/types'
import type { RecurringBuyPeriods } from 'data/components/recurringBuy/types'
import type { SwapAccountType, SwapBaseCounterTypes } from 'data/components/swap/types'
Expand Down Expand Up @@ -127,11 +128,11 @@ export type BuySellState = {
accumulatedTrades: RemoteDataType<string, Array<TradeAccumulatedItem>>
addBank: boolean | undefined
applePayInfo: undefined | ApplePayInfoType
balances: RemoteDataType<string, BSBalancesType>
buyQuote: RemoteDataType<string, BuyQuoteStateType>
balances: RemoteDataType<PartialClientErrorProperties, BSBalancesType>
buyQuote: RemoteDataType<PartialClientErrorProperties, BuyQuoteStateType>
card: RemoteDataType<string, BSCardType>
cardId: undefined | string
cards: RemoteDataType<string, Array<BSCardType>>
cards: RemoteDataType<PartialClientErrorProperties, Array<BSCardType>>
checkoutDotComAccountCodes: undefined | Array<string>
checkoutDotComApiKey: undefined | string
crossBorderLimits: RemoteDataType<string, CrossBorderLimits>
Expand All @@ -154,9 +155,9 @@ export type BuySellState = {
payment: RemoteDataType<string, undefined | PaymentValue>
providerDetails: RemoteDataType<string, ProviderDetailsType>
quote: RemoteDataType<string, BSQuoteType>
sddEligible: RemoteDataType<string, SDDEligibleType>
sddEligible: RemoteDataType<PartialClientErrorProperties, SDDEligibleType>
sddTransactionFinished: boolean
sddVerified: RemoteDataType<string, SDDVerifiedType>
sddVerified: RemoteDataType<PartialClientErrorProperties, SDDVerifiedType>
sellOrder: undefined | SwapOrderType
sellQuote: RemoteDataType<string, SwapQuoteStateType>
step: keyof typeof BuySellStepType
Expand Down

0 comments on commit 5e8d55f

Please sign in to comment.