Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at d42a2808ba53a049fc38f559feeddaa5a335f93f 97 lines 3.2 kB view raw
1import {XRPCError} from '@atproto/api' 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('OAuth credentials are not supported')) { 34 return t`This feature is not available when signed in with OAuth. Please manage your account through your hosting provider's website.` 35 } 36 if ( 37 str.includes('ScopeMissingError') || 38 str.includes('Missing required scope') 39 ) { 40 return t`This feature is not available with your current session. Please manage your account through your hosting provider's website, or sign out and sign back in to refresh your permissions.` 41 } 42 if (str.includes('Account has been suspended')) { 43 return t`Account has been suspended` 44 } 45 if (str.includes('Account is deactivated')) { 46 return t`Account is deactivated` 47 } 48 if (str.includes('Profile not found')) { 49 return t`Profile not found` 50 } 51 if (str.includes('Unable to resolve handle')) { 52 return t`Unable to resolve handle` 53 } 54 if (str.startsWith('Error: ')) { 55 return str.slice('Error: '.length) 56 } 57 return str 58} 59 60const NETWORK_ERRORS = [ 61 'Abort', 62 'Network request failed', 63 'Failed to fetch', 64 'Load failed', 65 'Upstream service unreachable', 66 'NetworkError when attempting to fetch resource', 67] 68 69export function isNetworkError(e: unknown) { 70 const str = String(e) 71 for (const err of NETWORK_ERRORS) { 72 if (str.includes(err)) { 73 return true 74 } 75 } 76 return false 77} 78 79export function isErrorMaybeAppPasswordPermissions(e: unknown) { 80 if (e instanceof XRPCError && e.error === 'TokenInvalid') { 81 return true 82 } 83 const str = String(e) 84 return str.includes('Bad token scope') || str.includes('Bad token method') 85} 86 87/** 88 * Intended to capture "User cancelled" or "Crop cancelled" errors 89 * that we often get from expo modules such @bsky.app/expo-image-crop-tool 90 * 91 * The exact name has changed in the past so let's just see if the string 92 * contains "cancel" 93 */ 94export function isCancelledError(e: unknown) { 95 const str = String(e).toLowerCase() 96 return str.includes('cancel') 97}