react-native icon indicating copy to clipboard operation
react-native copied to clipboard

[Android] Unrecoverable crash when calling setAccessibilityFocus on a component that is unmounting

Open Abbondanzo opened this issue 3 years ago • 2 comments

Description

When using the AccessibilityInfo.setAccessibilityFocus operator on Android, your app can fatally crash. This can happen while a component is in the process of being unmounted, and fails with the error: com.facebook.react.bridge.JSApplicationIllegalArgumentException: Could not find view with tag N.

We encountered this bug because we inserted an artificial delay on setting accessibility focus to small alert bars that appear when something goes wrong (i.e. the user forgot to fill a form input or a network request has failed). However, the user has the option to close that alert before it has finished animating. The expected behavior is for findNodeHandle to trigger an exception on the JS side but instead it yields a valid React tag which is then fed onto the native side via setAccessibilityFocus. Before that event is processed in the UIViewOperationQueue, the view is removed. Upon executing that event, the exception from above is raised and the user's app crashes.

Version

0.61.0 (and up)

Output of npx react-native info

System:
    OS: macOS 11.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 732.75 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.4 - ~/.nvm/versions/node/v14.17.4/bin/node
    Yarn: Not Found
    npm: 6.14.14 - ~/.nvm/versions/node/v14.17.4/bin/npm
    Watchman: 2021.10.04.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /Users/pabbondanzo/.gem/ruby/2.6.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 15.0, DriverKit 20.4, macOS 11.3, tvOS 15.0, watchOS 8.0
    Android SDK: Not Found
  IDEs:
    Android Studio: 2020.3 AI-203.7717.56.2031.7935034
    Xcode: 13.0/13A233 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.12 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: Not Found
    react-native: 0.64.2 => 0.64.2
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

This problem is unique to Android, but in effect the steps are:

  1. Just before a component is set to unmount (or, with a delayed timer) a reference to that component is held onto
  2. As the component is unmounting, call findNodeHandle with that component's ref to get the tag of that component, and feed that tag into AccessibilityInfo.setAccessibilityFocus
  3. The app should quickly crash with the exception JSApplicationIllegalArgumentException: Could not find view with tag N

The Expo snack below has an example application that will immediately crash when you press on the "Trigger Crash" button. The timer is there to signify that the app is in an unrecoverable state, and the "Reset" button should not be pressable

Snack, code example, screenshot, or link to a repository

https://snack.expo.dev/@abbondanzo/react-native-setaccessibilityfocus-crash

Abbondanzo avatar Feb 01 '22 21:02 Abbondanzo

Linking out to a similar issue from a few years ago. The view in question in this issue is marked correctly as accessible, so it's not completely related, but similar findings of what causes the crash: https://github.com/facebook/react-native/issues/22807

Abbondanzo avatar Feb 01 '22 21:02 Abbondanzo

It would be nice if we could catch the exception instead of crashing the app.

adarshem avatar Mar 08 '23 04:03 adarshem

Closed by https://github.com/facebook/react-native/pull/37002

cortinico avatar Sep 19 '23 13:09 cortinico