Skip to content

Commit a3e0b6a

Browse files
authored
Better lightning address error handling (#2089)
1 parent a724593 commit a3e0b6a

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

lib/lnurl.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { bech32 } from 'bech32'
33
import { lnAddrSchema } from './validate'
44
import { FetchTimeoutError } from '@/lib/fetch'
55
import { WALLET_CREATE_INVOICE_TIMEOUT_MS } from './constants'
6+
import { assertContentTypeJson, assertResponseOk, ResponseAssertError } from '@/lib/url'
67

78
export function encodeLNUrl (url) {
89
const words = bech32.toWords(Buffer.from(url.toString(), 'utf8'))
@@ -35,25 +36,33 @@ export async function lnAddrOptions (addr, { signal } = {}) {
3536
// support HTTP and HTTPS during development
3637
protocol = process.env.NEXT_PUBLIC_URL.split('://')[0]
3738
}
38-
const unexpectedErrorMessage = `An unexpected error occurred fetching the Lightning Address metadata for ${addr}. Check the address and try again.`
39-
let res
39+
40+
const unexpectedErrorMessage = 'Lightning address validation failed. Make sure you entered the correct address.'
41+
let body
4042
const url = `${protocol}://${domain}/.well-known/lnurlp/${name}`
4143
try {
42-
const req = await fetch(url, { signal })
43-
res = await req.json()
44+
const res = await fetch(url, { signal })
45+
assertResponseOk(res)
46+
assertContentTypeJson(res)
47+
body = await res.json()
4448
} catch (err) {
45-
console.log('Error fetching lnurlp', err)
49+
console.log('Error fetching lnurlp:', err)
50+
if (err instanceof ResponseAssertError) {
51+
throw err
52+
}
4653
if (err.name === 'TimeoutError') {
4754
throw new FetchTimeoutError('GET', url, WALLET_CREATE_INVOICE_TIMEOUT_MS)
4855
}
49-
// If `fetch` fails, or if `req.json` fails, catch it here and surface a reasonable error
56+
if (err.name === 'SyntaxError') {
57+
throw new Error(`GET ${url}: invalid JSON`)
58+
}
5059
throw new Error(unexpectedErrorMessage)
5160
}
52-
if (res.status === 'ERROR') {
61+
if (body.status === 'ERROR') {
5362
// if the response doesn't adhere to spec by providing a `reason` entry, returns a default error message
54-
throw new Error(res.reason ?? unexpectedErrorMessage)
63+
throw new Error(body.reason ?? unexpectedErrorMessage)
5564
}
5665

57-
const { minSendable, maxSendable, ...leftOver } = res
66+
const { minSendable, maxSendable, ...leftOver } = body
5867
return { min: minSendable / 1000, max: maxSendable / 1000, ...leftOver }
5968
}

lib/url.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export function parseNwcUrl (walletConnectUrl) {
213213
return params
214214
}
215215

216-
class ResponseAssertError extends Error {
216+
export class ResponseAssertError extends Error {
217217
constructor (res, { method } = {}) {
218218
if (method) {
219219
super(`${method} ${res.url}: ${res.status} ${res.statusText}`)

0 commit comments

Comments
 (0)