Skip to content

Commit c2e8aaf

Browse files
authored
chore(/payment): better error reporting (#1766)
1 parent 2b938cb commit c2e8aaf

File tree

8 files changed

+89
-31
lines changed

8 files changed

+89
-31
lines changed

src/components/pages/payment/constants.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,3 @@ export const PAYMENT_STATE = {
55
success: 'success',
66
failed: 'failed'
77
}
8-
9-
export const ERROR_MAIL_OPTS = {
10-
subject: 'Payment process error',
11-
body:
12-
'Hello,\n\nSomething bad happens trying to pay at microlink.io.\n\nCan you help me?'
13-
}

src/helpers/email-url.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const encode = ({ to, subject, body }) =>
2+
`mailto:${encodeURIComponent(to)}?subject=${encodeURIComponent(
3+
subject
4+
)}&body=${encodeURIComponent(body)}`
5+
6+
const paymentError = ({ subject, error }) => {
7+
let body =
8+
"Hello,\n\nSomething didn't work while updating my payment details."
9+
10+
if (error) {
11+
body += `\n\nThe error is:\n\n\`${error.stack}\``
12+
body += `\n\nMy browser is:\n\n\`${navigator.userAgent}\``
13+
}
14+
15+
body += '\n\nCan you assist me?'
16+
17+
return encode({
18+
19+
subject,
20+
body
21+
})
22+
}
23+
24+
const emailUrl = {
25+
encode,
26+
paymentError
27+
}
28+
29+
export default emailUrl

src/helpers/encode.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/helpers/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import aspectRatio from './aspect-ratio'
88
import hasChildren from './has-children'
99
import formatDate from './format-date'
1010
import proxyImage from './proxy-image'
11+
import emailUrl from './email-url'
1112
import getLines from './get-lines'
1213
import issueUrl from './issue-url'
1314
import template from './template'
@@ -17,7 +18,6 @@ import pdfUrl from './pdf-url'
1718
import trimMs from './trim-ms'
1819
import cdnUrl from './cdn-url'
1920
import decode from './decode'
20-
import encode from './encode'
2121
import isSSR from './is-ssr'
2222
import title from './title'
2323
import hash from './hash'
@@ -30,7 +30,7 @@ export {
3030
childrenText,
3131
childrenTextAll,
3232
decode,
33-
encode,
33+
emailUrl,
3434
formatDate,
3535
formatNumber,
3636
getLines,

src/pages/payment/index.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Caption, Layout } from 'components/patterns'
22
import React, { useState, useEffect } from 'react'
33
import { useQueryState } from 'components/hook'
4-
import { encode } from 'helpers'
4+
import emailUrl from 'helpers/email-url'
55
import { layout, theme } from 'theme'
66

77
import {
@@ -13,10 +13,7 @@ import {
1313
Meta
1414
} from 'components/elements'
1515

16-
import {
17-
PAYMENT_STATE,
18-
ERROR_MAIL_OPTS
19-
} from 'components/pages/payment/constants'
16+
import { PAYMENT_STATE } from 'components/pages/payment/constants'
2017

2118
const getTitle = paymentState => {
2219
switch (paymentState) {
@@ -46,9 +43,9 @@ const getCaption = paymentState => {
4643
Payment not processed.{' '}
4744
<Link
4845
css={theme({ pt: 2 })}
49-
href={`mailto:[email protected]?${encode(ERROR_MAIL_OPTS)}`}
46+
href={emailUrl.paymentError({ subject: 'Error during checkout' })}
5047
>
51-
Contact us
48+
Click to request assistance.
5249
</Link>
5350
</>
5451
)

src/pages/payment/update.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
/* global fetch */
22

33
import { useFingerprint, useSiteMetadata, useQueryState } from 'components/hook'
4+
import { PAYMENT_STATE } from 'components/pages/payment/constants'
5+
import { Caption, Layout } from 'components/patterns'
6+
import { loadStripe } from '@stripe/stripe-js/pure'
7+
import React, { useEffect, useState } from 'react'
8+
import emailUrl from 'helpers/email-url'
9+
import once from 'helpers/once'
10+
411
import {
512
colors,
613
fonts,
@@ -10,11 +17,6 @@ import {
1017
transition,
1118
theme
1219
} from 'theme'
13-
import { Caption, Layout } from 'components/patterns'
14-
import { loadStripe } from '@stripe/stripe-js/pure'
15-
import React, { useEffect, useState } from 'react'
16-
import { encode } from 'helpers'
17-
import once from 'helpers/once'
1820

1921
import {
2022
Box,
@@ -35,11 +37,6 @@ import {
3537
useElements
3638
} from '@stripe/react-stripe-js'
3739

38-
import {
39-
PAYMENT_STATE,
40-
ERROR_MAIL_OPTS
41-
} from 'components/pages/payment/constants'
42-
4340
const fetchOnce = once(fetch)
4441

4542
const redirectUrl = (paymentState, id) => {
@@ -62,7 +59,7 @@ const getTitle = paymentState => {
6259
}
6360
}
6461

65-
const getCaption = paymentState => {
62+
const getCaption = (paymentState, error) => {
6663
switch (paymentState) {
6764
case PAYMENT_STATE.redirected:
6865
return (
@@ -79,9 +76,12 @@ const getCaption = paymentState => {
7976
Payment not updated.{' '}
8077
<Link
8178
css={theme({ pt: 2 })}
82-
href={`mailto:[email protected]?${encode(ERROR_MAIL_OPTS)}`}
79+
href={emailUrl.paymentError({
80+
subject: 'Error updating my payment details',
81+
error
82+
})}
8383
>
84-
Contact us
84+
Click to request assistance.
8585
</Link>
8686
.
8787
</>
@@ -96,6 +96,7 @@ const CheckoutForm = ({
9696
id,
9797
paymentState,
9898
setPaymentState,
99+
setError,
99100
token
100101
}) => {
101102
const elements = useElements()
@@ -124,6 +125,7 @@ const CheckoutForm = ({
124125
if (error) throw error
125126
} catch (error) {
126127
console.error(error)
128+
setError(error)
127129
setPaymentState(PAYMENT_STATE.failed)
128130
}
129131
}
@@ -157,6 +159,7 @@ export const Head = () => <Meta title='Payment' />
157159

158160
const PaymentUpdatePage = () => {
159161
const [isLoading, setIsLoading] = useState(true)
162+
const [error, setError] = useState(null)
160163
const [query] = useQueryState()
161164
const {
162165
stripeKey,
@@ -215,7 +218,10 @@ const PaymentUpdatePage = () => {
215218
})}
216219
titleize={false}
217220
>
218-
{getCaption(isLoading ? PAYMENT_STATE.redirected : paymentState)}
221+
{getCaption(
222+
isLoading ? PAYMENT_STATE.redirected : paymentState,
223+
error
224+
)}
219225
</Caption>
220226
{!isLoading && !query.status && (
221227
<Box css={theme({ pt: [3, null, 4], width: 7 })}>
@@ -251,6 +257,7 @@ const PaymentUpdatePage = () => {
251257
id={query.id}
252258
paymentState={paymentState}
253259
setPaymentState={setPaymentState}
260+
setError={setError}
254261
token={query.token}
255262
/>
256263
</Elements>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
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"`;
4+
5+
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"`;

test/helpers/email-url.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { expect, describe, it } from 'vitest'
2+
3+
import emailUrl from '../../src/helpers/email-url.js'
4+
5+
describe('emailUrl', () => {
6+
describe('.paymentError', () => {
7+
it('with error', () => {
8+
const error = new Error('oh no')
9+
error.stack =
10+
'Error: oh no\n at Context.<anonymous> (/path/to/test/helpers/email-url.js:10:19)\n at processImmediate (internal/timers.js:456:21)'
11+
12+
const url = emailUrl.paymentError({
13+
subject: 'Error during checkout',
14+
error
15+
})
16+
17+
expect(url).toMatchSnapshot()
18+
})
19+
20+
it('without error', () => {
21+
const url = emailUrl.paymentError({
22+
subject: 'Error during checkout'
23+
})
24+
25+
expect(url).toMatchSnapshot()
26+
})
27+
})
28+
})

0 commit comments

Comments
 (0)