Skip to content

fix(android): broaden malformed-JSON catch in NativeProxy handleEvent#9989

Open
raid5 wants to merge 1 commit into
software-mansion:mainfrom
raid5:fix-android-nativeproxy-malformed-json-catch
Open

fix(android): broaden malformed-JSON catch in NativeProxy handleEvent#9989
raid5 wants to merge 1 commit into
software-mansion:mainfrom
raid5:fix-android-nativeproxy-malformed-json-catch

Conversation

@raid5

@raid5 raid5 commented Jul 17, 2026

Copy link
Copy Markdown

Summary

NativeProxy::handleEvent (packages/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp) wraps the JSON deserialization of an incoming event payload in a try/catch whose intent — per its own comment, // Ignore events with malformed JSON payload. — is to silently drop events whose payload cannot be parsed:

try {
  payload = jsi::Value::createFromJsonUtf8(uiRuntime, ...);
} catch (std::exception &) {
  // Ignore events with malformed JSON payload.
  return;
}

The problem is that the catch only matches std::exception &. On Hermes, the JSI value thrown when JSON parsing fails is not guaranteed to derive from std::exception, so a malformed payload slips past this handler and propagates up, crashing the app instead of being ignored.

The fix broadens the catch to catch (...), so any failure from createFromJsonUtf8 is swallowed as the comment already intends. This is consistent with the existing event->toString() try/catch a few lines above in the same function, which already uses catch (...) for the analogous "payload cannot be represented" case.

This is a one-line, behavior-preserving broadening of an existing error path — no new behavior is introduced; it just makes the intended "ignore malformed payload" path actually fire on Hermes.

This fix was prepared with AI assistance and reviewed by a human before submission.

Test plan

This change has been running in a shipping React Native app on a Hermes release build with the New Architecture enabled, where it eliminated a crash caused by malformed event payloads reaching handleEvent.

Root-cause repro on a Hermes release build:

  1. Attach a Reanimated event handler (e.g. useAnimatedScrollHandler or a gesture-driven handler) so handleEvent runs.
  2. Dispatch a native event whose serialized payload is not valid JSON for createFromJsonUtf8.
  3. Before this change the app crashes, because the JSI value Hermes throws is not a std::exception and escapes the catch (std::exception &). After this change the event is silently ignored, exactly as the existing comment intends.

Well-formed payloads are unaffected — only the exception type matched by the catch was widened. This is a native C++ change; the JS test suite does not cover it.

The try/catch around jsi::Value::createFromJsonUtf8() in
NativeProxy::handleEvent only caught std::exception&. On Hermes, the
JSI value thrown for a malformed JSON payload is not guaranteed to
derive from std::exception, so a bad event payload escaped the handler
and crashed the app instead of being ignored.

Broaden the catch to catch(...) so malformed-JSON event payloads are
swallowed exactly as the existing "Ignore events with malformed JSON
payload." comment intends. This matches the toString() try/catch a few
lines above, which already uses catch(...).
@tomekzaw tomekzaw self-assigned this Jul 18, 2026
@tomekzaw

Copy link
Copy Markdown
Member

Hello @raid5, thanks for submitting the PR! I'm happy with merging it in its current shape. Do you have a repro that we can use to make sure that there are no regressions in the future?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants