forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useCallback} from 'react'
2import {msg} from '@lingui/core/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('OAuth credentials are not supported')) {
70 return {
71 raw,
72 clean: _(
73 msg`This feature is not available when signed in with OAuth. Please manage your account through your hosting provider's website.`,
74 ),
75 }
76 }
77
78 if (raw.includes('Rate Limit Exceeded')) {
79 return {
80 raw,
81 clean: _(
82 msg`You've reached the maximum number of requests allowed. Please try again later.`,
83 ),
84 }
85 }
86
87 if (raw.startsWith('Error: ')) {
88 raw = raw.slice('Error: '.length)
89 }
90
91 return {
92 raw,
93 clean: undefined,
94 }
95 },
96 [_],
97 )
98}
99
100const NETWORK_ERRORS = [
101 'Abort',
102 'Network request failed',
103 'Failed to fetch',
104 'Load failed',
105 'Upstream service unreachable',
106]
107
108export function isNetworkError(e: unknown) {
109 const str = String(e)
110 for (const err of NETWORK_ERRORS) {
111 if (str.includes(err)) {
112 return true
113 }
114 }
115 return false
116}