From 5b44aa962f5c50eacff08a8c3feee5fb8db752cb Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 22 Mar 2024 12:14:47 -0500 Subject: [PATCH] Wrap Button children in an error boundary (#3340) * Wrap Button children in an error boundary * Check for Trans component --- src/components/Button.tsx | 67 +++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 0e22944a..67c33fa0 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,19 +1,21 @@ 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 {Trans} from '@lingui/macro' -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 +405,51 @@ export function Button({ )} - {typeof children === 'string' ? ( - {children} - ) : typeof children === 'function' ? ( - children(context) - ) : ( - children - )} + + {/* @ts-ignore */} + {typeof children === 'string' || children?.type === Trans ? ( + /* @ts-ignore */ + {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()