Skip to content

Commit

Permalink
chore(/payment): better error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jan 23, 2025
1 parent 2b938cb commit 03ca0b2
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 31 deletions.
6 changes: 0 additions & 6 deletions src/components/pages/payment/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,3 @@ export const PAYMENT_STATE = {
success: 'success',
failed: 'failed'
}

export const ERROR_MAIL_OPTS = {
subject: 'Payment process error',
body:
'Hello,\n\nSomething bad happens trying to pay at microlink.io.\n\nCan you help me?'
}
29 changes: 29 additions & 0 deletions src/helpers/email-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const encode = ({ to, subject, body }) =>
`mailto:${encodeURIComponent(to)}?subject=${encodeURIComponent(
subject
)}&body=${encodeURIComponent(body)}`

const paymentError = ({ subject, error }) => {
let body =
"Hello,\n\nSomething didn't work while updating my payment details."

if (error) {
body += `\n\nThe error is:\n\n\`${error.stack}\``
body += `\n\nMy browser is:\n\n\`${navigator.userAgent}\``
}

body += '\n\nCan you assist me?'

return encode({
to: '[email protected]',
subject,
body
})
}

const emailUrl = {
encode,
paymentError
}

export default emailUrl
2 changes: 0 additions & 2 deletions src/helpers/encode.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import aspectRatio from './aspect-ratio'
import hasChildren from './has-children'
import formatDate from './format-date'
import proxyImage from './proxy-image'
import emailUrl from './email-url'
import getLines from './get-lines'
import issueUrl from './issue-url'
import template from './template'
Expand All @@ -17,7 +18,6 @@ import pdfUrl from './pdf-url'
import trimMs from './trim-ms'
import cdnUrl from './cdn-url'
import decode from './decode'
import encode from './encode'
import isSSR from './is-ssr'
import title from './title'
import hash from './hash'
Expand All @@ -30,7 +30,7 @@ export {
childrenText,
childrenTextAll,
decode,
encode,
emailUrl,
formatDate,
formatNumber,
getLines,
Expand Down
11 changes: 4 additions & 7 deletions src/pages/payment/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Caption, Layout } from 'components/patterns'
import React, { useState, useEffect } from 'react'
import { useQueryState } from 'components/hook'
import { encode } from 'helpers'
import emailUrl from 'helpers/email-url'
import { layout, theme } from 'theme'

import {
Expand All @@ -13,10 +13,7 @@ import {
Meta
} from 'components/elements'

import {
PAYMENT_STATE,
ERROR_MAIL_OPTS
} from 'components/pages/payment/constants'
import { PAYMENT_STATE } from 'components/pages/payment/constants'

const getTitle = paymentState => {
switch (paymentState) {
Expand Down Expand Up @@ -46,9 +43,9 @@ const getCaption = paymentState => {
Payment not processed.{' '}
<Link
css={theme({ pt: 2 })}
href={`mailto:[email protected]?${encode(ERROR_MAIL_OPTS)}`}
href={emailUrl.paymentError({ subject: 'Error during checkout' })}
>
Contact us
Click to request assistance.
</Link>
</>
)
Expand Down
35 changes: 21 additions & 14 deletions src/pages/payment/update.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
/* global fetch */

import { useFingerprint, useSiteMetadata, useQueryState } from 'components/hook'
import { PAYMENT_STATE } from 'components/pages/payment/constants'
import { Caption, Layout } from 'components/patterns'
import { loadStripe } from '@stripe/stripe-js/pure'
import React, { useEffect, useState } from 'react'
import emailUrl from 'helpers/email-url'
import once from 'helpers/once'

import {
colors,
fonts,
Expand All @@ -10,11 +17,6 @@ import {
transition,
theme
} from 'theme'
import { Caption, Layout } from 'components/patterns'
import { loadStripe } from '@stripe/stripe-js/pure'
import React, { useEffect, useState } from 'react'
import { encode } from 'helpers'
import once from 'helpers/once'

import {
Box,
Expand All @@ -35,11 +37,6 @@ import {
useElements
} from '@stripe/react-stripe-js'

import {
PAYMENT_STATE,
ERROR_MAIL_OPTS
} from 'components/pages/payment/constants'

const fetchOnce = once(fetch)

const redirectUrl = (paymentState, id) => {
Expand All @@ -62,7 +59,7 @@ const getTitle = paymentState => {
}
}

const getCaption = paymentState => {
const getCaption = (paymentState, error) => {
switch (paymentState) {
case PAYMENT_STATE.redirected:
return (
Expand All @@ -79,9 +76,12 @@ const getCaption = paymentState => {
Payment not updated.{' '}
<Link
css={theme({ pt: 2 })}
href={`mailto:[email protected]?${encode(ERROR_MAIL_OPTS)}`}
href={emailUrl.paymentError({
subject: 'Error updating my payment details',
error
})}
>
Contact us
Click to request assistance.
</Link>
.
</>
Expand All @@ -96,6 +96,7 @@ const CheckoutForm = ({
id,
paymentState,
setPaymentState,
setError,
token
}) => {
const elements = useElements()
Expand Down Expand Up @@ -124,6 +125,7 @@ const CheckoutForm = ({
if (error) throw error
} catch (error) {
console.error(error)
setError(error)
setPaymentState(PAYMENT_STATE.failed)
}
}
Expand Down Expand Up @@ -157,6 +159,7 @@ export const Head = () => <Meta title='Payment' />

const PaymentUpdatePage = () => {
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
const [query] = useQueryState()
const {
stripeKey,
Expand Down Expand Up @@ -215,7 +218,10 @@ const PaymentUpdatePage = () => {
})}
titleize={false}
>
{getCaption(isLoading ? PAYMENT_STATE.redirected : paymentState)}
{getCaption(
isLoading ? PAYMENT_STATE.redirected : paymentState,
error
)}
</Caption>
{!isLoading && !query.status && (
<Box css={theme({ pt: [3, null, 4], width: 7 })}>
Expand Down Expand Up @@ -251,6 +257,7 @@ const PaymentUpdatePage = () => {
id={query.id}
paymentState={paymentState}
setPaymentState={setPaymentState}
setError={setError}
token={query.token}
/>
</Elements>
Expand Down
5 changes: 5 additions & 0 deletions test/helpers/__snapshots__/email-url.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`emailUrl > .paymentError > with error 1`] = `"mailto:hello%40microlink.io?subject=Error%20during%20checkout&body=Hello%2C%0A%0ASomething%20didn't%20work%20while%20updating%20my%20payment%20details.%0A%0AThe%20error%20is%3A%0A%0A%60Error%3A%20oh%20no%0A%20%20%20%20at%20Context.%3Canonymous%3E%20(%2Fpath%2Fto%2Ftest%2Fhelpers%2Femail-url.js%3A10%3A19)%0A%20%20%20%20at%20processImmediate%20(internal%2Ftimers.js%3A456%3A21)%60%0A%0AMy%20browser%20is%3A%0A%0A%60Node.js%2F22%60%0A%0ACan%20you%20assist%20me%3F"`;

exports[`emailUrl > .paymentError > without error 1`] = `"mailto:hello%40microlink.io?subject=Error%20during%20checkout&body=Hello%2C%0A%0ASomething%20didn't%20work%20while%20updating%20my%20payment%20details.%0A%0ACan%20you%20assist%20me%3F"`;
28 changes: 28 additions & 0 deletions test/helpers/email-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expect, describe, it } from 'vitest'

import emailUrl from '../../src/helpers/email-url.js'

describe('emailUrl', () => {
describe('.paymentError', () => {
it('with error', () => {
const error = new Error('oh no')
error.stack =
'Error: oh no\n at Context.<anonymous> (/path/to/test/helpers/email-url.js:10:19)\n at processImmediate (internal/timers.js:456:21)'

const url = emailUrl.paymentError({
subject: 'Error during checkout',
error
})

expect(url).toMatchSnapshot()
})

it('without error', () => {
const url = emailUrl.paymentError({
subject: 'Error during checkout'
})

expect(url).toMatchSnapshot()
})
})
})

0 comments on commit 03ca0b2

Please sign in to comment.