forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {XRPCError} from '@atproto/xrpc'
2import {t} from '@lingui/core/macro'
3
4export function cleanError(str: any): string {
5 if (!str) {
6 return ''
7 }
8 if (typeof str !== 'string') {
9 str = str.toString()
10 }
11 if (isNetworkError(str)) {
12 return t`Unable to connect. Please check your internet connection and try again.`
13 }
14 if (
15 str.includes('Upstream Failure') ||
16 str.includes('NotEnoughResources') ||
17 str.includes('pipethrough network error')
18 ) {
19 return t`The server appears to be experiencing issues. Please try again in a few moments.`
20 }
21 /**
22 * @see https://github.com/bluesky-social/atproto/blob/255cfcebb54332a7129af768a93004e22c6858e3/packages/pds/src/actor-store/preference/transactor.ts#L24
23 */
24 if (
25 str.includes('Do not have authorization to set preferences') &&
26 str.includes('app.bsky.actor.defs#personalDetailsPref')
27 ) {
28 return t`You cannot update your birthdate while using an app password. Please sign in with your main password to update your birthdate.`
29 }
30 if (str.includes('Bad token scope') || str.includes('Bad token method')) {
31 return t`This feature is not available while using an App Password. Please sign in with your main password.`
32 }
33 if (str.includes('Account has been suspended')) {
34 return t`Account has been suspended`
35 }
36 if (str.includes('Account is deactivated')) {
37 return t`Account is deactivated`
38 }
39 if (str.includes('Profile not found')) {
40 return t`Profile not found`
41 }
42 if (str.includes('Unable to resolve handle')) {
43 return t`Unable to resolve handle`
44 }
45 if (str.startsWith('Error: ')) {
46 return str.slice('Error: '.length)
47 }
48 return str
49}
50
51const NETWORK_ERRORS = [
52 'Abort',
53 'Network request failed',
54 'Failed to fetch',
55 'Load failed',
56 'Upstream service unreachable',
57 'NetworkError when attempting to fetch resource',
58]
59
60export function isNetworkError(e: unknown) {
61 const str = String(e)
62 for (const err of NETWORK_ERRORS) {
63 if (str.includes(err)) {
64 return true
65 }
66 }
67 return false
68}
69
70export function isErrorMaybeAppPasswordPermissions(e: unknown) {
71 if (e instanceof XRPCError && e.error === 'TokenInvalid') {
72 return true
73 }
74 const str = String(e)
75 return str.includes('Bad token scope') || str.includes('Bad token method')
76}
77
78/**
79 * Intended to capture "User cancelled" or "Crop cancelled" errors
80 * that we often get from expo modules such @bsky.app/expo-image-crop-tool
81 *
82 * The exact name has changed in the past so let's just see if the string
83 * contains "cancel"
84 */
85export function isCancelledError(e: unknown) {
86 const str = String(e).toLowerCase()
87 return str.includes('cancel')
88}