From db713ae021d280a64d5e423ab918ca5b69839f22 Mon Sep 17 00:00:00 2001 From: Shubham Kumar Savita Date: Wed, 6 May 2026 13:38:03 -0700 Subject: [PATCH] Add error handling in InspectorPackagerConnection::connect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Fix a SIGSEGV crash that can occur during WebSocket connection in the React Native JS inspector when `JCxxInspectorPackagerConnectionDelegateImpl::connectWebSocket()` fails (for example, due to allocation failure when constructing the WebSocket delegate hybrid object, or a JNI exception thrown from the Java side). Previously `InspectorPackagerConnection::Impl::connect()` had no error handling around the `connectWebSocket` call — any exception (`std::bad_alloc`, `JniException`, etc.) would propagate unhandled and terminate the process. ### Changes 1. **`InspectorPackagerConnection.cpp`**: Wrap `connectWebSocket` in try-catch. On failure, log the error, reset the WebSocket, and trigger `reconnect()` (existing 2-second retry mechanism). This is consistent with how other error paths in the same class already handle failures (e.g., `didFailWithError` and `didClose` both call `reconnect()`). 2. **`JCxxInspectorPackagerConnectionDelegateImpl.cpp`**: Add a null check on the JNI return value before calling `wrapInUniquePtr()` to prevent a null dereference if the Java method returns null. Changelog: [General][Fixed] - Handle exceptions thrown during WebSocket connect in `InspectorPackagerConnection` to avoid native crashes when the JS inspector fails to connect [Android][Fixed] - Add null check on JNI return value in `JCxxInspectorPackagerConnectionDelegateImpl::connectWebSocket` to prevent null dereference Differential Revision: D100956267 --- .../JCxxInspectorPackagerConnectionDelegateImpl.cpp | 3 +++ .../jsinspector-modern/InspectorPackagerConnection.cpp | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.cpp index d10f8f295e58..6fffe6cb9fe4 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.cpp @@ -30,6 +30,9 @@ JCxxInspectorPackagerConnectionDelegateImpl::connectWebSocket( "connectWebSocket"); auto jWebSocket = method( self(), url, make_global(JWebSocketDelegate::newObjectCxxArgs(delegate))); + if (!jWebSocket) { + return nullptr; + } return jWebSocket->wrapInUniquePtr(); } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp b/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp index 4edf6e0c6e88..71f53d2e8bd5 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp @@ -341,9 +341,12 @@ void InspectorPackagerConnection::Impl::connect() { webSocket_ = delegate_->connectWebSocket(url_, weak_from_this()); } catch (const std::exception& e) { LOG(ERROR) << "Failed to create WebSocket connection: " << e.what(); - reconnect(); + webSocket_.reset(); } catch (...) { LOG(ERROR) << "Failed to create WebSocket connection: unknown error"; + webSocket_.reset(); + } + if (!webSocket_ && !closed_) { reconnect(); } }