Skip to content

Commit e9b431c

Browse files
authored
chore: add new "no price from dealer" error (#2404)
* chore: add new NoDealerPriceDataAvailableError error * refactor: change dealer error handling to use regexes
1 parent 5259466 commit e9b431c

File tree

4 files changed

+52
-19
lines changed

4 files changed

+52
-19
lines changed

src/domain/dealer-price/errors.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export class NoConnectionToDealerError extends DealerPriceServiceError {
1010
export class DealerStalePriceError extends DealerPriceServiceError {
1111
level = ErrorLevel.Critical
1212
}
13+
export class NoDealerPriceDataAvailableError extends DealerPriceServiceError {
14+
level = ErrorLevel.Critical
15+
}
1316
export class UnknownDealerPriceServiceError extends DealerPriceServiceError {
1417
level = ErrorLevel.Critical
1518
}

src/graphql/error-map.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
OnChainPaymentError,
2222
PhoneProviderError,
2323
UnexpectedClientError,
24+
DealerError,
2425
} from "@graphql/error"
2526
import { baseLogger } from "@services/logger"
2627

@@ -225,6 +226,10 @@ export const mapError = (error: ApplicationError): CustomApolloError => {
225226
message = "Unsupported IP for rewards."
226227
return new ValidationInternalError({ message, logger: baseLogger })
227228

229+
case "NoDealerPriceDataAvailableError":
230+
message = "No price data from dealer to perform USD operation."
231+
return new DealerError({ message, logger: baseLogger })
232+
228233
case "NoConnectionToDealerError":
229234
message = "No connection to dealer to perform USD operation."
230235
return new DealerOfflineError({ message, logger: baseLogger })

src/graphql/error.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,17 @@ export class LndOfflineError extends CustomApolloError {
166166
}
167167
}
168168

169+
export class DealerError extends CustomApolloError {
170+
constructor(errData: PartialBy<CustomApolloErrorData, "logger" | "forwardToClient">) {
171+
super({
172+
code: "DEALER_ERROR",
173+
forwardToClient: true,
174+
...errData,
175+
logger: baseLogger,
176+
})
177+
}
178+
}
179+
169180
export class DealerOfflineError extends CustomApolloError {
170181
constructor(errData: PartialBy<CustomApolloErrorData, "logger" | "forwardToClient">) {
171182
super({

src/services/dealer-price/dealer-price.ts

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { paymentAmountFromNumber, WalletCurrency } from "@domain/shared"
99
import {
1010
DealerStalePriceError,
1111
NoConnectionToDealerError,
12+
NoDealerPriceDataAvailableError,
1213
UnknownDealerPriceServiceError,
1314
} from "@domain/dealer-price"
1415

@@ -109,7 +110,7 @@ export const DealerPriceService = (
109110
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Usd })
110111
} catch (error) {
111112
baseLogger.error({ error }, "GetCentsFromSatsForImmediateBuy unable to fetch price")
112-
return parseDealerErrors(error)
113+
return handleDealerErrors(error)
113114
}
114115
}
115116

@@ -129,7 +130,7 @@ export const DealerPriceService = (
129130
{ error },
130131
"GetCentsFromSatsForImmediateSell unable to fetch price",
131132
)
132-
return parseDealerErrors(error)
133+
return handleDealerErrors(error)
133134
}
134135
}
135136

@@ -146,7 +147,7 @@ export const DealerPriceService = (
146147
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Usd })
147148
} catch (error) {
148149
baseLogger.error({ error }, "GetCentsFromSatsForFutureBuy unable to fetch price")
149-
return parseDealerErrors(error)
150+
return handleDealerErrors(error)
150151
}
151152
}
152153

@@ -163,7 +164,7 @@ export const DealerPriceService = (
163164
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Usd })
164165
} catch (error) {
165166
baseLogger.error({ error }, "GetCentsFromSatsForFutureSell unable to fetch price")
166-
return parseDealerErrors(error)
167+
return handleDealerErrors(error)
167168
}
168169
}
169170

@@ -180,7 +181,7 @@ export const DealerPriceService = (
180181
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Btc })
181182
} catch (error) {
182183
baseLogger.error({ error }, "GetSatsFromCentsForImmediateBuy unable to fetch price")
183-
return parseDealerErrors(error)
184+
return handleDealerErrors(error)
184185
}
185186
}
186187

@@ -200,7 +201,7 @@ export const DealerPriceService = (
200201
{ error },
201202
"GetSatsFromCentsForImmediateSell unable to fetch price",
202203
)
203-
return parseDealerErrors(error)
204+
return handleDealerErrors(error)
204205
}
205206
}
206207

@@ -217,7 +218,7 @@ export const DealerPriceService = (
217218
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Btc })
218219
} catch (error) {
219220
baseLogger.error({ error }, "GetSatsFromCentsForFutureBuy unable to fetch price")
220-
return parseDealerErrors(error)
221+
return handleDealerErrors(error)
221222
}
222223
}
223224

@@ -234,7 +235,7 @@ export const DealerPriceService = (
234235
return paymentAmountFromNumber({ amount, currency: WalletCurrency.Btc })
235236
} catch (error) {
236237
baseLogger.error({ error }, "GetSatsFromCentsForFutureSell unable to fetch price")
237-
return parseDealerErrors(error)
238+
return handleDealerErrors(error)
238239
}
239240
}
240241

@@ -248,7 +249,7 @@ export const DealerPriceService = (
248249
return toWalletPriceRatio(response.getRatioInCentsPerSatoshis())
249250
} catch (error) {
250251
baseLogger.error({ error }, "GetCentsPerSatsExchangeMidRate unable to fetch price")
251-
return parseDealerErrors(error)
252+
return handleDealerErrors(error)
252253
}
253254
}
254255

@@ -272,15 +273,28 @@ export const DealerPriceService = (
272273
})
273274
}
274275

275-
/* eslint @typescript-eslint/ban-ts-comment: "off" */
276-
// @ts-ignore-next-line no-implicit-any error
277-
const parseDealerErrors = (error): DealerPriceServiceError => {
278-
if (error.details === "No connection established") {
279-
return new NoConnectionToDealerError()
280-
}
281-
if (error.message.includes("StalePrice")) {
282-
return new DealerStalePriceError()
283-
}
276+
const handleDealerErrors = (err: Error | string) => {
277+
const errMsg = typeof err === "string" ? err : err.message
278+
279+
const match = (knownErrDetail: RegExp): boolean => knownErrDetail.test(errMsg)
280+
281+
switch (true) {
282+
case match(KnownDealerErrorDetails.NoConnection):
283+
return new NoConnectionToDealerError(errMsg)
284284

285-
return new UnknownDealerPriceServiceError(error.message)
285+
case match(KnownDealerErrorDetails.StalePrice):
286+
return new DealerStalePriceError(errMsg)
287+
288+
case match(KnownDealerErrorDetails.NoPriceData):
289+
return new NoDealerPriceDataAvailableError(errMsg)
290+
291+
default:
292+
return new UnknownDealerPriceServiceError(errMsg)
293+
}
286294
}
295+
296+
export const KnownDealerErrorDetails = {
297+
NoConnection: /No connection established/,
298+
StalePrice: /StalePrice/,
299+
NoPriceData: /No price data available/,
300+
} as const

0 commit comments

Comments
 (0)