Bluesky app fork with some witchin' additions 💫

Catch crop cancelled errors (#9451)

authored by samuel.fm and committed by GitHub 4d1b1bb2 507531e1

Changed files
+35 -11
src
lib
strings
screens
Onboarding
StepProfile
state
view
+12
src/lib/strings/errors.ts
··· 52 52 const str = String(e) 53 53 return str.includes('Bad token scope') || str.includes('Bad token method') 54 54 } 55 + 56 + /** 57 + * Intended to capture "User cancelled" or "Crop cancelled" errors 58 + * that we often get from expo modules such expo-image-crop-tool 59 + * 60 + * The exact name has changed in the past so let's just see if the string 61 + * contains "cancel" 62 + */ 63 + export function isCancelledError(e: unknown) { 64 + const str = String(e).toLowerCase() 65 + return str.includes('cancel') 66 + }
+13 -5
src/screens/Onboarding/StepProfile/index.tsx
··· 15 15 import {getDataUriSize} from '#/lib/media/util' 16 16 import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' 17 17 import {logEvent, useGate} from '#/lib/statsig/statsig' 18 + import {isCancelledError} from '#/lib/strings/errors' 19 + import {logger} from '#/logger' 18 20 import {isNative, isWeb} from '#/platform/detection' 19 21 import { 20 22 DescriptionText, ··· 184 186 if (!image) return 185 187 186 188 if (!isWeb) { 187 - image = await openCropper({ 188 - imageUri: image.path, 189 - shape: 'circle', 190 - aspectRatio: 1 / 1, 191 - }) 189 + try { 190 + image = await openCropper({ 191 + imageUri: image.path, 192 + shape: 'circle', 193 + aspectRatio: 1 / 1, 194 + }) 195 + } catch (e) { 196 + if (!isCancelledError(e)) { 197 + logger.error('Failed to crop avatar in onboarding', {error: e}) 198 + } 199 + } 192 200 } 193 201 image = await compressIfNeeded(image, 1000000) 194 202
+2 -1
src/state/gallery.ts
··· 17 17 import {openCropper} from '#/lib/media/picker' 18 18 import {type PickerImage} from '#/lib/media/picker.shared' 19 19 import {getDataUriSize} from '#/lib/media/util' 20 + import {isCancelledError} from '#/lib/strings/errors' 20 21 import {isNative} from '#/platform/detection' 21 22 22 23 export type ImageTransformation = { ··· 143 144 }, 144 145 } 145 146 } catch (e) { 146 - if (e instanceof Error && e.message.includes('User cancelled')) { 147 + if (!isCancelledError(e)) { 147 148 return img 148 149 } 149 150
+4 -3
src/view/com/util/UserAvatar.tsx
··· 26 26 import {type PickerImage} from '#/lib/media/picker.shared' 27 27 import {makeProfileLink} from '#/lib/routes/links' 28 28 import {sanitizeDisplayName} from '#/lib/strings/display-names' 29 + import {isCancelledError} from '#/lib/strings/errors' 29 30 import {sanitizeHandle} from '#/lib/strings/handles' 30 31 import {logger} from '#/logger' 31 32 import {isAndroid, isNative, isWeb} from '#/platform/detection' ··· 407 408 setRawImage(await createComposerImage(item)) 408 409 editImageDialogControl.open() 409 410 } 410 - } catch (e: any) { 411 + } catch (e) { 411 412 // Don't log errors for cancelling selection to sentry on ios or android 412 - if (!String(e).toLowerCase().includes('cancel')) { 413 - logger.error('Failed to crop banner', {error: e}) 413 + if (!isCancelledError(e)) { 414 + logger.error('Failed to crop avatar', {error: e}) 414 415 } 415 416 } 416 417 }, [
+4 -2
src/view/com/util/UserBanner.tsx
··· 12 12 import {compressIfNeeded} from '#/lib/media/manip' 13 13 import {openCamera, openCropper, openPicker} from '#/lib/media/picker' 14 14 import {type PickerImage} from '#/lib/media/picker.shared' 15 + import {isCancelledError} from '#/lib/strings/errors' 15 16 import {logger} from '#/logger' 16 17 import {isAndroid, isNative} from '#/platform/detection' 17 18 import { ··· 87 88 setRawImage(await createComposerImage(items[0])) 88 89 editImageDialogControl.open() 89 90 } 90 - } catch (e: any) { 91 - if (!String(e).includes('Canceled')) { 91 + } catch (e) { 92 + // Don't log errors for cancelling selection to sentry on ios or android 93 + if (!isCancelledError(e)) { 92 94 logger.error('Failed to crop banner', {error: e}) 93 95 } 94 96 }