From 65bd978367340eb8a83073143f94e6110c1afd75 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 22 Mar 2024 11:31:53 -0500 Subject: [PATCH] Wrap Button children in an error boundary --- src/components/Button.tsx | 64 +++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 0e22944a33..a3cf185c9a 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,19 +1,20 @@ import React from 'react' import { - Pressable, - Text, - PressableProps, - TextProps, - ViewStyle, AccessibilityProps, - View, - TextStyle, - StyleSheet, + Pressable, + PressableProps, StyleProp, + StyleSheet, + Text, + TextProps, + TextStyle, + View, + ViewStyle, } from 'react-native' import LinearGradient from 'react-native-linear-gradient' -import {useTheme, atoms as a, tokens, android, flatten} from '#/alf' +import {logger} from '#/logger' +import {android, atoms as a, flatten, tokens, useTheme} from '#/alf' import {Props as SVGIconProps} from '#/components/icons/common' import {normalizeTextStyles} from '#/components/Typography' @@ -403,18 +404,49 @@ export function Button({ )} - {typeof children === 'string' ? ( - {children} - ) : typeof children === 'function' ? ( - children(context) - ) : ( - children - )} + + {typeof children === 'string' ? ( + {children} + ) : typeof children === 'function' ? ( + children(context) + ) : ( + children + )} + ) } +export class ButtonTextErrorBoundary extends React.Component< + React.PropsWithChildren<{}>, + {hasError: boolean; error: Error | undefined} +> { + public state = { + hasError: false, + error: undefined, + } + + public static getDerivedStateFromError(error: Error) { + return {hasError: true, error} + } + + public componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + logger.error('ButtonTextErrorBoundary caught an error', { + message: error.message, + errorInfo, + }) + } + + public render() { + if (this.state.hasError) { + return ERROR + } + + return this.props.children + } +} + export function useSharedButtonTextStyles() { const t = useTheme() const {color, variant, disabled, size} = useButtonContext()