forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useCallback} from 'react'
2import {msg} from '@lingui/macro'
3import {useLingui} from '@lingui/react'
4
5type CleanedError = {
6 raw: string | undefined
7 clean: string | undefined
8}
9
10export function useCleanError() {
11 const {_} = useLingui()
12
13 return useCallback<(error?: any) => CleanedError>(
14 error => {
15 if (!error)
16 return {
17 raw: undefined,
18 clean: undefined,
19 }
20
21 let raw = error.toString()
22
23 if (isNetworkError(raw)) {
24 return {
25 raw,
26 clean: _(
27 msg`Unable to connect. Please check your internet connection and try again.`,
28 ),
29 }
30 }
31
32 if (
33 raw.includes('Upstream Failure') ||
34 raw.includes('NotEnoughResources') ||
35 raw.includes('pipethrough network error')
36 ) {
37 return {
38 raw,
39 clean: _(
40 msg`The server appears to be experiencing issues. Please try again in a few moments.`,
41 ),
42 }
43 }
44
45 /**
46 * @see https://github.com/bluesky-social/atproto/blob/255cfcebb54332a7129af768a93004e22c6858e3/packages/pds/src/actor-store/preference/transactor.ts#L24
47 */
48 if (
49 raw.includes('Do not have authorization to set preferences') &&
50 raw.includes('app.bsky.actor.defs#personalDetailsPref')
51 ) {
52 return {
53 raw,
54 clean: _(
55 msg`You cannot update your birthdate while using an app password. Please sign in with your main password to update your birthdate.`,
56 ),
57 }
58 }
59
60 if (raw.includes('Bad token scope') || raw.includes('Bad token method')) {
61 return {
62 raw,
63 clean: _(
64 msg`This feature is not available while using an app password. Please sign in with your main password.`,
65 ),
66 }
67 }
68
69 if (raw.includes('Rate Limit Exceeded')) {
70 return {
71 raw,
72 clean: _(
73 msg`You've reached the maximum number of requests allowed. Please try again later.`,
74 ),
75 }
76 }
77
78 if (raw.startsWith('Error: ')) {
79 raw = raw.slice('Error: '.length)
80 }
81
82 return {
83 raw,
84 clean: undefined,
85 }
86 },
87 [_],
88 )
89}
90
91const NETWORK_ERRORS = [
92 'Abort',
93 'Network request failed',
94 'Failed to fetch',
95 'Load failed',
96 'Upstream service unreachable',
97]
98
99export function isNetworkError(e: unknown) {
100 const str = String(e)
101 for (const err of NETWORK_ERRORS) {
102 if (str.includes(err)) {
103 return true
104 }
105 }
106 return false
107}