11import { addBreadcrumb , getCurrentHub } from '@sentry/core' ;
22import type { SeverityLevel } from '@sentry/types' ;
3- import { logger } from '@sentry/utils' ;
3+ import { dropUndefinedKeys , logger } from '@sentry/utils' ;
44import * as React from 'react' ;
55import type { GestureResponderEvent } from 'react-native' ;
66import { StyleSheet , View } from 'react-native' ;
@@ -189,50 +189,7 @@ class TouchEventBoundary extends React.Component<TouchEventBoundaryProps> {
189189 break ;
190190 }
191191
192- const props = currentInst . memoizedProps ?? { } ;
193- const info : TouchedComponentInfo = { } ;
194-
195- // provided by @sentry /babel-plugin-component-annotate
196- if (
197- typeof props [ SENTRY_COMPONENT_PROP_KEY ] === 'string' &&
198- props [ SENTRY_COMPONENT_PROP_KEY ] . length > 0 &&
199- props [ SENTRY_COMPONENT_PROP_KEY ] !== 'unknown'
200- ) {
201- info . name = props [ SENTRY_COMPONENT_PROP_KEY ] ;
202- }
203- if (
204- typeof props [ SENTRY_ELEMENT_PROP_KEY ] === 'string' &&
205- props [ SENTRY_ELEMENT_PROP_KEY ] . length > 0 &&
206- props [ SENTRY_ELEMENT_PROP_KEY ] !== 'unknown'
207- ) {
208- info . element = props [ SENTRY_ELEMENT_PROP_KEY ] ;
209- }
210- if (
211- typeof props [ SENTRY_FILE_PROP_KEY ] === 'string' &&
212- props [ SENTRY_FILE_PROP_KEY ] . length > 0 &&
213- props [ SENTRY_FILE_PROP_KEY ] !== 'unknown'
214- ) {
215- info . file = props [ SENTRY_FILE_PROP_KEY ] ;
216- }
217-
218- // use custom label if provided by the user, or displayName if available
219- const labelValue =
220- typeof props [ SENTRY_LABEL_PROP_KEY ] === 'string'
221- ? props [ SENTRY_LABEL_PROP_KEY ]
222- : // For some reason type narrowing doesn't work as expected with indexing when checking it all in one go in
223- // the "check-label" if sentence, so we have to assign it to a variable here first
224- typeof this . props . labelName === 'string'
225- ? props [ this . props . labelName ]
226- : undefined ;
227-
228- if ( typeof labelValue === 'string' && labelValue . length > 0 ) {
229- info . label = labelValue ;
230- }
231-
232- if ( ! info . name && currentInst . elementType ?. displayName ) {
233- info . name = currentInst . elementType ?. displayName ;
234- }
235-
192+ const info = getTouchedComponentInfo ( currentInst , this . props . labelName ) ;
236193 this . _pushIfNotIgnored ( touchPath , info ) ;
237194
238195 currentInst = currentInst . return ;
@@ -252,7 +209,11 @@ class TouchEventBoundary extends React.Component<TouchEventBoundaryProps> {
252209 /**
253210 * Pushes the name to the componentTreeNames array if it is not ignored.
254211 */
255- private _pushIfNotIgnored ( touchPath : TouchedComponentInfo [ ] , value : TouchedComponentInfo ) : boolean {
212+ private _pushIfNotIgnored ( touchPath : TouchedComponentInfo [ ] , value : TouchedComponentInfo | undefined ) : boolean {
213+ if ( ! value ) {
214+ return false ;
215+ }
216+
256217 if ( ! value . name && ! value . label ) {
257218 return false ;
258219 }
@@ -273,6 +234,55 @@ class TouchEventBoundary extends React.Component<TouchEventBoundaryProps> {
273234 }
274235}
275236
237+ function getTouchedComponentInfo ( currentInst : ElementInstance , labelKey : string | undefined ) : TouchedComponentInfo | undefined {
238+ const props = currentInst . memoizedProps ;
239+ if ( ! props ) {
240+ // Early return if no props are available, as we can't extract any useful information
241+ return undefined ;
242+ }
243+
244+ // provided by @sentry /babel-plugin-component-annotate
245+ const info : TouchedComponentInfo = { } ;
246+ info . name = getComponentName ( props ) || currentInst . elementType ?. displayName ;
247+ info . element = getElementName ( props ) ;
248+ info . file = getFileName ( props ) ;
249+
250+ // `sentry-label` or user defined label key
251+ info . label = getLabelValue ( props , labelKey ) ;
252+ return dropUndefinedKeys ( info ) ;
253+ }
254+
255+ function getComponentName ( props : Record < string , unknown > ) : string | undefined {
256+ return typeof props [ SENTRY_COMPONENT_PROP_KEY ] === 'string' &&
257+ props [ SENTRY_COMPONENT_PROP_KEY ] . length > 0 &&
258+ props [ SENTRY_COMPONENT_PROP_KEY ] !== 'unknown' &&
259+ props [ SENTRY_COMPONENT_PROP_KEY ] || undefined ;
260+ }
261+
262+ function getElementName ( props : Record < string , unknown > ) : string | undefined {
263+ return typeof props [ SENTRY_ELEMENT_PROP_KEY ] === 'string' &&
264+ props [ SENTRY_ELEMENT_PROP_KEY ] . length > 0 &&
265+ props [ SENTRY_ELEMENT_PROP_KEY ] !== 'unknown' &&
266+ props [ SENTRY_ELEMENT_PROP_KEY ] || undefined ;
267+ }
268+
269+ function getFileName ( props : Record < string , unknown > ) : string | undefined {
270+ return typeof props [ SENTRY_FILE_PROP_KEY ] === 'string' &&
271+ props [ SENTRY_FILE_PROP_KEY ] . length > 0 &&
272+ props [ SENTRY_FILE_PROP_KEY ] !== 'unknown' &&
273+ props [ SENTRY_FILE_PROP_KEY ] || undefined ;
274+ }
275+
276+ function getLabelValue ( props : Record < string , unknown > , labelKey : string | undefined ) : string | undefined {
277+ return typeof props [ SENTRY_LABEL_PROP_KEY ] === 'string' && props [ SENTRY_LABEL_PROP_KEY ] . length > 0
278+ ? props [ SENTRY_LABEL_PROP_KEY ] as string
279+ // For some reason type narrowing doesn't work as expected with indexing when checking it all in one go in
280+ // the "check-label" if sentence, so we have to assign it to a variable here first
281+ : typeof labelKey === 'string' && typeof props [ labelKey ] == 'string' && ( props [ labelKey ] as string ) . length > 0
282+ ? props [ labelKey ] as string
283+ : undefined ;
284+ }
285+
276286/**
277287 * Convenience Higher-Order-Component for TouchEventBoundary
278288 * @param WrappedComponent any React Component
0 commit comments