Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/backend/src/graphql/resolvers/quote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { createWalletAddress } from '../../tests/walletAddress'
import { createQuote } from '../../tests/quote'
import { truncateTables } from '../../tests/tableManager'
import {
QuoteError,
errorToMessage,
errorToCode
errorToCode,
QuoteErrorCode
} from '../../open_payments/quote/errors'
import { QuoteService } from '../../open_payments/quote/service'
import { Quote as QuoteModel } from '../../open_payments/quote/model'
Expand Down Expand Up @@ -249,9 +249,9 @@ describe('Quote Resolvers', (): void => {
expect(error).toBeInstanceOf(ApolloError)
expect((error as ApolloError).graphQLErrors).toContainEqual(
expect.objectContaining({
message: errorToMessage[QuoteError.UnknownWalletAddress],
message: errorToMessage[QuoteErrorCode.UnknownWalletAddress],
extensions: expect.objectContaining({
code: errorToCode[QuoteError.UnknownWalletAddress]
code: errorToCode[QuoteErrorCode.UnknownWalletAddress]
})
})
)
Expand Down
5 changes: 3 additions & 2 deletions packages/backend/src/graphql/resolvers/quote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ export const createQuote: MutationResolvers<ApolloContext>['createQuote'] =
options.receiveAmount = args.input.receiveAmount
const quoteOrError = await quoteService.create(options)
if (isQuoteError(quoteOrError)) {
throw new GraphQLError(errorToMessage[quoteOrError], {
throw new GraphQLError(errorToMessage[quoteOrError.type], {
extensions: {
code: errorToCode[quoteOrError]
code: errorToCode[quoteOrError.type],
details: quoteOrError.details
}
})
} else
Expand Down
15 changes: 8 additions & 7 deletions packages/backend/src/open_payments/payment/outgoing/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '../../../accounting/errors'
import { GraphQLErrorCode } from '../../../graphql/errors'
import { PaymentMethodHandlerError } from '../../../payment-method/handler/errors'
import { QuoteError } from '../../quote/errors'
import { QuoteErrorCode } from '../../quote/errors'

export enum OutgoingPaymentError {
UnknownWalletAddress = 'UnknownWalletAddress',
Expand All @@ -21,15 +21,16 @@ export enum OutgoingPaymentError {
}

export const quoteErrorToOutgoingPaymentError: Record<
QuoteError,
QuoteErrorCode,
OutgoingPaymentError
> = {
[QuoteError.UnknownWalletAddress]: OutgoingPaymentError.UnknownWalletAddress,
[QuoteError.InvalidAmount]: OutgoingPaymentError.InvalidAmount,
[QuoteError.InvalidReceiver]: OutgoingPaymentError.InvalidReceiver,
[QuoteError.InactiveWalletAddress]:
[QuoteErrorCode.UnknownWalletAddress]:
OutgoingPaymentError.UnknownWalletAddress,
[QuoteErrorCode.InvalidAmount]: OutgoingPaymentError.InvalidAmount,
[QuoteErrorCode.InvalidReceiver]: OutgoingPaymentError.InvalidReceiver,
[QuoteErrorCode.InactiveWalletAddress]:
OutgoingPaymentError.InactiveWalletAddress,
[QuoteError.NonPositiveReceiveAmount]:
[QuoteErrorCode.NonPositiveReceiveAmount]:
OutgoingPaymentError.NegativeReceiveAmount
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { PaymentMethodHandlerService } from '../../../payment-method/handler/ser
import { PaymentMethodHandlerError } from '../../../payment-method/handler/errors'
import { mockRatesApi } from '../../../tests/rates'
import { UnionOmit } from '../../../shared/utils'
import { QuoteError } from '../../quote/errors'
import { QuoteError, QuoteErrorCode } from '../../quote/errors'
import { withConfigOverride } from '../../../tests/helpers'
import { TelemetryService } from '../../../telemetry/service'
import { getPageTests } from '../../../shared/baseModel.test'
Expand Down Expand Up @@ -747,10 +747,11 @@ describe('OutgoingPaymentService', (): void => {
assetScale: receiverWalletAddress.asset.scale
}

const quoteCreateResponse = QuoteError.InvalidAmount
const quoteSpy = jest
.spyOn(quoteService, 'create')
.mockImplementationOnce(async () => quoteCreateResponse)
.mockImplementationOnce(
async () => new QuoteError(QuoteErrorCode.InvalidAmount)
)

const payment = await outgoingPaymentService.create({
walletAddressId,
Expand All @@ -759,7 +760,7 @@ describe('OutgoingPaymentService', (): void => {
})

expect(isOutgoingPaymentError(payment)).toBeTruthy()
expect(payment).toBe(quoteCreateResponse)
expect(payment).toBe(OutgoingPaymentError.InvalidAmount)
expect(quoteSpy).toHaveBeenCalledWith({
walletAddressId,
receiver: incomingPaymentUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ async function createOutgoingPayment(
stopTimerQuote()

if (isQuoteError(quoteOrError)) {
return quoteErrorToOutgoingPaymentError[quoteOrError]
return quoteErrorToOutgoingPaymentError[quoteOrError.type]
}
quoteId = quoteOrError.id
} else {
Expand Down
52 changes: 31 additions & 21 deletions packages/backend/src/open_payments/quote/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { GraphQLErrorCode } from '../../graphql/errors'

export enum QuoteError {
export class QuoteError extends Error {
public type: QuoteErrorCode
public details?: Record<string, unknown>

constructor(type: QuoteErrorCode, details?: Record<string, unknown>) {
super(errorToMessage[type], details)
this.type = type
this.details = details
}
}

export enum QuoteErrorCode {
UnknownWalletAddress = 'UnknownWalletAddress',
InvalidAmount = 'InvalidAmount',
InvalidReceiver = 'InvalidReceiver',
Expand All @@ -9,35 +20,34 @@ export enum QuoteError {
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
export const isQuoteError = (o: any): o is QuoteError =>
Object.values(QuoteError).includes(o)
export const isQuoteError = (o: any): o is QuoteError => o instanceof QuoteError

export const errorToHTTPCode: {
[key in QuoteError]: number
[key in QuoteErrorCode]: number
} = {
[QuoteError.UnknownWalletAddress]: 404,
[QuoteError.InvalidAmount]: 400,
[QuoteError.InvalidReceiver]: 400,
[QuoteError.InactiveWalletAddress]: 400,
[QuoteError.NonPositiveReceiveAmount]: 400
[QuoteErrorCode.UnknownWalletAddress]: 404,
[QuoteErrorCode.InvalidAmount]: 400,
[QuoteErrorCode.InvalidReceiver]: 400,
[QuoteErrorCode.InactiveWalletAddress]: 400,
[QuoteErrorCode.NonPositiveReceiveAmount]: 400
}

export const errorToCode: {
[key in QuoteError]: GraphQLErrorCode
[key in QuoteErrorCode]: GraphQLErrorCode
} = {
[QuoteError.UnknownWalletAddress]: GraphQLErrorCode.NotFound,
[QuoteError.InvalidAmount]: GraphQLErrorCode.BadUserInput,
[QuoteError.InvalidReceiver]: GraphQLErrorCode.BadUserInput,
[QuoteError.InactiveWalletAddress]: GraphQLErrorCode.Inactive,
[QuoteError.NonPositiveReceiveAmount]: GraphQLErrorCode.BadUserInput
[QuoteErrorCode.UnknownWalletAddress]: GraphQLErrorCode.NotFound,
[QuoteErrorCode.InvalidAmount]: GraphQLErrorCode.BadUserInput,
[QuoteErrorCode.InvalidReceiver]: GraphQLErrorCode.BadUserInput,
[QuoteErrorCode.InactiveWalletAddress]: GraphQLErrorCode.Inactive,
[QuoteErrorCode.NonPositiveReceiveAmount]: GraphQLErrorCode.BadUserInput
}

export const errorToMessage: {
[key in QuoteError]: string
[key in QuoteErrorCode]: string
} = {
[QuoteError.UnknownWalletAddress]: 'unknown wallet address',
[QuoteError.InvalidAmount]: 'invalid amount',
[QuoteError.InvalidReceiver]: 'invalid receiver',
[QuoteError.InactiveWalletAddress]: 'inactive wallet address',
[QuoteError.NonPositiveReceiveAmount]: 'non-positive receive amount'
[QuoteErrorCode.UnknownWalletAddress]: 'unknown wallet address',
[QuoteErrorCode.InvalidAmount]: 'invalid amount',
[QuoteErrorCode.InvalidReceiver]: 'invalid receiver',
[QuoteErrorCode.InactiveWalletAddress]: 'inactive wallet address',
[QuoteErrorCode.NonPositiveReceiveAmount]: 'non-positive receive amount'
}
5 changes: 3 additions & 2 deletions packages/backend/src/open_payments/quote/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ async function createQuote(

if (isQuoteError(quoteOrErr)) {
throw new OpenPaymentsServerRouteError(
errorToHTTPCode[quoteOrErr],
errorToMessage[quoteOrErr]
errorToHTTPCode[quoteOrErr.type],
errorToMessage[quoteOrErr.type],
quoteOrErr.details
)
}

Expand Down
Loading
Loading