Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animated events must have event data #704

Closed
musicode opened this issue Apr 4, 2020 · 22 comments · Fixed by software-mansion/react-native-gesture-handler#1171
Closed

Animated events must have event data #704

musicode opened this issue Apr 4, 2020 · 22 comments · Fixed by software-mansion/react-native-gesture-handler#1171
Assignees
Labels
Missing repro This issue need minimum repro scenario

Comments

@musicode
Copy link

musicode commented Apr 4, 2020

java.lang.IllegalArgumentException: Animated events must have event data.
	at com.swmansion.reanimated.nodes.EventNode.receiveEvent(Unknown Source:50)
	at com.swmansion.gesturehandler.react.i.a(Unknown Source:8)
	at com.swmansion.reanimated.b.b(Unknown Source:47)
	at com.swmansion.reanimated.b.a(Unknown Source:25)
	at com.swmansion.reanimated.b.a(Unknown Source:0)
	at com.swmansion.reanimated.b$a.b(Unknown Source:2)
	at com.facebook.react.uimanager.e.a(Unknown Source:0)
	at com.facebook.react.modules.core.g$d.a(Unknown Source:46)
	at com.facebook.react.modules.core.a$a$a.doFrame(Unknown Source:2)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1055)
	at android.view.Choreographer.doCallbacks(Choreographer.java:875)
	at android.view.Choreographer.doFrame(Choreographer.java:772)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1042)
	at android.os.Handler.handleCallback(Handler.java:888)
	at android.os.Handler.dispatchMessage(Handler.java:100)
	at android.os.Looper.loop(Looper.java:213)
	at android.app.ActivityThread.main(ActivityThread.java:8169)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
@jakub-gonet
Copy link
Member

Hi @musicode,
thanks for reporting!

Can you provide a minimal working example on snack that triggers this exception and provide versions of React, React Native, React Native Gesture Handler and React Native Reanimated?

@musicode
Copy link
Author

musicode commented Apr 5, 2020

I dont't know how to reproduce this issue, because this error stack is reported by a bug analysis system.

@jakub-gonet
Copy link
Member

jakub-gonet commented Apr 5, 2020

All right, could you provide packages versions then? It was happening before or after you upgraded to certain version of gesture handler / reanimated?

@musicode
Copy link
Author

musicode commented Apr 5, 2020

    "react": "16.11.0",
    "react-native": "0.62.1",
    "react-native-device-info": "^5.5.3",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-permissions": "^2.0.10",
    "react-native-reanimated": "^1.7.1",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.4.0",
    "react-native-simple-store": "^2.0.2",
    "react-native-swiper": "1.6.0-rc.3",
    "react-native-tab-view": "^2.13.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-video": "^4.4.5",
    "react-native-webview": "^9.0.1",
    "react-navigation": "4.3.3",
    "react-navigation-stack": "^2.3.7",
    "react-navigation-tabs": "^2.8.7",

I upgrade react-native to 0.62 last week.

@jakub-gonet jakub-gonet added the Missing repro This issue need minimum repro scenario label Apr 6, 2020
@jakub-gonet
Copy link
Member

It's probably related to this issue

@chgsilva
Copy link

same issue here, any solutions?

@jakub-gonet
Copy link
Member

@chgsilva,
being honest I was unable to reproduce call stack - I get tab view expo example crashing, but couldn't get much more than that, maybe it's related to being in a release mode. Without inspecting what payload from RNGH causes event data to be null we're basically out of luck fixing this because I was only able to reproduce it in a release app.

If you have reproducible code that causes the crash and can be debugged it'd be really appreciated.

@drb1
Copy link

drb1 commented Jun 4, 2020

same issue in release mode, is there any solution

@mym0404
Copy link

mym0404 commented Jul 14, 2020

same in Android
This bug is not occurred 100%. Intermittent

image

Fatal Exception: java.lang.IllegalArgumentException: Animated events must have event data.
       at com.swmansion.reanimated.nodes.EventNode.receiveEvent(EventNode.java:63)
       at com.swmansion.gesturehandler.react.RNGestureHandlerStateChangeEvent.dispatch(RNGestureHandlerStateChangeEvent.java:80)
       at com.swmansion.reanimated.NodesManager.handleEvent(NodesManager.java:394)
       at com.swmansion.reanimated.NodesManager.onAnimationFrame(NodesManager.java:148)
       at com.swmansion.reanimated.NodesManager.access$000(NodesManager.java:55)
       at com.swmansion.reanimated.NodesManager$1.doFrameGuarded(NodesManager.java:108)
       at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
       at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
       at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:997)
       at android.view.Choreographer.doCallbacks(Choreographer.java:797)
       at android.view.Choreographer.doFrame(Choreographer.java:728)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:984)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:237)
       at android.app.ActivityThread.main(ActivityThread.java:8125)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

@jakub-gonet jakub-gonet self-assigned this Jul 21, 2020
@aliceathens
Copy link

aliceathens commented Aug 11, 2020

+1 same issues for our app in production:
"@react-native-community/async-storage": "^1.9.0",
"@react-native-community/masked-view": "^0.1.9",
"@react-native-community/netinfo": "^5.7.0",
"@react-native-firebase/analytics": "7.1.2",
"@react-native-firebase/app": "7.1.4",
"@react-native-firebase/crashlytics": "7.1.3",
"@react-navigation/bottom-tabs": "^5.6.1",
"@react-navigation/drawer": "^5.4.0",
"@react-navigation/material-top-tabs": "^5.2.12",
"@react-navigation/native": "^5.1.4",
"@react-navigation/stack": "^5.2.9",
"base-64": "^0.1.0",
"color": "^3.1.2",
"compare-versions": "^3.6.0",
"d3-shape": "^1.3.7",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"moment-timezone": "^0.5.28",
"prop-types": "^15.7.2",
"react": "16.11.0",
"react-native": "0.62.0",
"react-native-bcrypt": "^2.4.0",
"react-native-code-push": "^6.2.0",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "1.4.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.4.0",
"react-native-snap-carousel": "^3.9.0",
"react-native-splash-screen": "^3.2.0",
"react-native-svg": "^12.0.3",
"react-native-tab-view": "^2.14.4",
"react-native-touch-id": "^4.4.1",
"react-native-ux-cam": "^5.1.15",
"react-native-vector-icons": "^6.6.0",
"react-native-webview": "^9.2.1",
"react-redux": "5.1.0",
"redux": "^3.7.2",
"redux-form": "^7.0.3",
"redux-saga": "0.16.0",
"reselect": "^4.0.0"

Fatal Exception: java.lang.IllegalArgumentException: Animated events must have event data.
       at com.swmansion.reanimated.nodes.EventNode.receiveEvent(EventNode.java:63)
       at com.swmansion.gesturehandler.react.RNGestureHandlerStateChangeEvent.dispatch(RNGestureHandlerStateChangeEvent.java:80)
       at com.swmansion.reanimated.NodesManager.handleEvent(NodesManager.java:402)
       at com.swmansion.reanimated.NodesManager.onAnimationFrame(NodesManager.java:148)
       at com.swmansion.reanimated.NodesManager.access$000(NodesManager.java:55)
       at com.swmansion.reanimated.NodesManager$1.doFrameGuarded(NodesManager.java:108)
       at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
       at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
       at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970)
       at android.view.Choreographer.doCallbacks(Choreographer.java:796)
       at android.view.Choreographer.doFrame(Choreographer.java:727)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
       at android.os.Handler.handleCallback(Handler.java:938)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:223)
       at android.app.ActivityThread.main(ActivityThread.java:7656)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)```

@kangfenmao
Copy link

java.lang.IllegalArgumentException: Animated events must have event data.
	at com.swmansion.reanimated.nodes.EventNode.receiveEvent(EventNode.java:63)
	at com.swmansion.gesturehandler.react.RNGestureHandlerStateChangeEvent.dispatch(RNGestureHandlerStateChangeEvent.java:80)
	at com.swmansion.reanimated.NodesManager.handleEvent(NodesManager.java:394)
	at com.swmansion.reanimated.NodesManager.onAnimationFrame(NodesManager.java:148)
	at com.swmansion.reanimated.NodesManager.access$000(NodesManager.java:55)
	at com.swmansion.reanimated.NodesManager$1.doFrameGuarded(NodesManager.java:108)
	at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
	at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
	at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1055)
	at android.view.Choreographer.doCallbacks(Choreographer.java:875)
	at android.view.Choreographer.doFrame(Choreographer.java:772)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1042)
	at android.os.Handler.handleCallback(Handler.java:900)
	at android.os.Handler.dispatchMessage(Handler.java:103)
	at android.os.Looper.loop(Looper.java:219)
	at android.app.ActivityThread.main(ActivityThread.java:8349)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

@jakub-gonet
Copy link
Member

I'm keeping eye on this issue, but any reproduction example would be very helpful.

@kangfenmao
Copy link

kangfenmao commented Aug 11, 2020

@Override
  public void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event) {
    if (event == null) {
      // throw new IllegalArgumentException("Animated events must have event data.");
      return;
    }

    for (int i = 0; i < mMapping.size(); i++) {
      EventMap eventMap = mMapping.get(i);
      Double value = eventMap.lookupValue(event);
      if (value != null) {
        mNodesManager.findNodeById(eventMap.nodeID, ValueNode.class).setValue(value);
      }
    }
  }

Don't throw an exception here. This caused a large number of crash 😂

@jakub-gonet
Copy link
Member

@kangfenmao, as I said here I'd want to fix the root of the problem instead of ignoring malformed events.

@jakub-gonet
Copy link
Member

Hi guys, could you check if software-mansion/react-native-gesture-handler#1171 fixes those crashes for you?

jakub-gonet added a commit to software-mansion/react-native-gesture-handler that referenced this issue Aug 21, 2020
## Description

This commit fixes a threading issue connected with `enabled` property of gesture handlers. Changing this property in JS called `updateGestureHandler` in the RNGH Java module which in turn called `setEnabled`. `setEnabled` cancels handler by using `cancel()` method if it was in an active state previously.
This method was mistakenly called directly from the native modules thread - state transition methods are intended to be called from the UI thread.

This made GH orchestrator call `handler.dispatchStateChange()` on the wrong thread. This caused event listeners to receive the event on a non-UI thread (`NodeManager.onEventDispatch()` from Reanimated) via `EventDispatcher`.

Reanimated handles non-UI events in `onEventDispatch` (e.g. `onLayout` event) by adding them to the internal queue and posting frame callback if it wasn't posted previously (`onAnimationFrame()` wasn't called). Then any queued event is handled on UI thread in the next frame. 
Problem is, `EventDispatcher` first calls `onEventDispatch()` of any registered listeners and then runs `maybePostFrameCallbackFromNonUI()` which tries to post frame callback dispatching and disposing events from JS thread. 

So there was a possibility that we:
1. queue event in `NodeManager.onEventDispatch` in native modules thread
2. handle and **dispose** event in `EventDispatcher`, setting extra data to `null`
3. take the event from the queue and try handling it in the `NodeManager.onAnimationFrame`, raising exception.

The solution to that problem is to always run `cancel()` (and any other `stateChange` method) on UI thread.


- Fixes react-navigation/react-navigation/issues/6403
- Fixes satya164/react-native-tab-view/issues/976
- Fixes software-mansion/react-native-reanimated/issues/704

## Test plan

Huge thanks to the @midoushitongtong who provided small enough code example which reproduced this issue.

```jsx
import * as React from 'react';
import { View, StyleSheet, Dimensions, Text } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';

const FirstRoute = () => (
  <View style={[styles.scene, { backgroundColor: '#ff4081' }]}>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
  </View>
);

const initialLayout = { width: Dimensions.get('window').width };

const InnerTab = () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([{ key: 'first', title: 'First' }]);

  const renderScene = SceneMap({
    first: FirstRoute,
  });

  return (
    <TabView
      lazy
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
};

export default () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([
    { key: 'a', title: 'a' },
    { key: 'b', title: 'b' },
    { key: 'c', title: 'c' },
  ]);

  const renderScene = SceneMap({
    a: InnerTab,
    b: InnerTab,
    c: InnerTab,
  });

  return (
    <TabView
      lazy
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
};

const styles = StyleSheet.create({
  scene: {
    flex: 1,
  },
});
```


When swiping rapidly in the first or last tab app crashed. After running `cancel()` on UI thread it stopped crashing. Also made sure that the Example app still works correctly.
@daaanigm
Copy link

Hi guys, could you check if software-mansion/react-native-gesture-handler#1171 fixes those crashes for you?

Will a release be created with this fix?

@jakub-gonet
Copy link
Member

In the near future, yes. We need to make sure that changing state of gestures are done from one thread and this needs a little bit more testing.

@zmnv
Copy link

zmnv commented Nov 20, 2020

@jakub-gonet hello! is it fixed for now moment?

some of our users with Android has:

java.lang.IllegalArgumentException: Animated events must have event data.
    at com.swmansion.reanimated.nodes.EventNode.receiveEvent(EventNode.java:63)

@jakub-gonet
Copy link
Member

Fix for that crash was included in the 1.8.1 release of the gesture handler.

braincore pushed a commit to braincore/react-native-gesture-handler that referenced this issue Mar 4, 2021
…sion#1171)

## Description

This commit fixes a threading issue connected with `enabled` property of gesture handlers. Changing this property in JS called `updateGestureHandler` in the RNGH Java module which in turn called `setEnabled`. `setEnabled` cancels handler by using `cancel()` method if it was in an active state previously.
This method was mistakenly called directly from the native modules thread - state transition methods are intended to be called from the UI thread.

This made GH orchestrator call `handler.dispatchStateChange()` on the wrong thread. This caused event listeners to receive the event on a non-UI thread (`NodeManager.onEventDispatch()` from Reanimated) via `EventDispatcher`.

Reanimated handles non-UI events in `onEventDispatch` (e.g. `onLayout` event) by adding them to the internal queue and posting frame callback if it wasn't posted previously (`onAnimationFrame()` wasn't called). Then any queued event is handled on UI thread in the next frame. 
Problem is, `EventDispatcher` first calls `onEventDispatch()` of any registered listeners and then runs `maybePostFrameCallbackFromNonUI()` which tries to post frame callback dispatching and disposing events from JS thread. 

So there was a possibility that we:
1. queue event in `NodeManager.onEventDispatch` in native modules thread
2. handle and **dispose** event in `EventDispatcher`, setting extra data to `null`
3. take the event from the queue and try handling it in the `NodeManager.onAnimationFrame`, raising exception.

The solution to that problem is to always run `cancel()` (and any other `stateChange` method) on UI thread.


- Fixes react-navigation/react-navigation/issues/6403
- Fixes satya164/react-native-tab-view/issues/976
- Fixes software-mansion/react-native-reanimated/issues/704

## Test plan

Huge thanks to the @midoushitongtong who provided small enough code example which reproduced this issue.

```jsx
import * as React from 'react';
import { View, StyleSheet, Dimensions, Text } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';

const FirstRoute = () => (
  <View style={[styles.scene, { backgroundColor: '#ff4081' }]}>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
    <Text>aaaaa</Text>
  </View>
);

const initialLayout = { width: Dimensions.get('window').width };

const InnerTab = () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([{ key: 'first', title: 'First' }]);

  const renderScene = SceneMap({
    first: FirstRoute,
  });

  return (
    <TabView
      lazy
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
};

export default () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([
    { key: 'a', title: 'a' },
    { key: 'b', title: 'b' },
    { key: 'c', title: 'c' },
  ]);

  const renderScene = SceneMap({
    a: InnerTab,
    b: InnerTab,
    c: InnerTab,
  });

  return (
    <TabView
      lazy
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
};

const styles = StyleSheet.create({
  scene: {
    flex: 1,
  },
});
```


When swiping rapidly in the first or last tab app crashed. After running `cancel()` on UI thread it stopped crashing. Also made sure that the Example app still works correctly.
@girish54321
Copy link

girish54321 commented Jun 23, 2021

Hi @jakub-gonet there no version 1.8.1 of the gesture handler
can you tell me which one to install to fix this bug?

@jakub-gonet
Copy link
Member

You can install any version from 1.8.0 upwards.

@girish54321
Copy link

Thanks, @jakub-gonet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Missing repro This issue need minimum repro scenario
Projects
None yet
10 participants