Skip to content

Conversation

@ohah
Copy link
Owner

@ohah ohah commented Jan 18, 2026

Problem

When extracting response bodies from network requests using the fetch API in React Native, the following issues occurred:

  1. Initial approach: Attempted to handle Fetch requests using only the XHR hook, but response detection did not work properly
  2. Errors after re-enabling FetchHook: After re-enabling FetchHook, errors occurred when calling Promise methods:
    • Cannot read property 'then' of undefined - Promise chain connection failure
    • Cannot read property 'constructor' of undefined - Context issue when calling text() method
    • Cannot read property '_noBody' of undefined - Response body extraction failure

Root Cause

  1. XHR hook alone is insufficient: React Native's fetch API uses XHR internally, but response body extraction requires processing at the Fetch API level
  2. Incorrect Promise method calls: In FetchHook, when calling Promise methods (text(), then(), catch()), call() was used instead of callWithThis(), causing incorrect this context binding

Solution

  1. Re-enable FetchHook

    • Response detection did not work properly with XHR hook alone, so FetchHook was re-enabled
    • Implemented collaboration logic between FetchHook and XHRHook
  2. Use callWithThis for Promise method calls

    • text() method: Bind clonedResponse as this
    • then() method: Bind textPromiseObj as this
    • catch() method: Bind firstPromiseObj as this
  3. Improve collaboration logic between Fetch and XHR

    • Added global flags for Fetch request detection (g_isFetchRequestActive, g_activeFetchRequestId)
    • Prevent duplicate requestWillBeSent transmission in XHRHook when it's a Fetch request
    • Store response body in g_responseData after extraction in FetchHook
    • Send responseReceived and loadingFinished events in XHRHook

Changes

  • NetworkHook.cpp: Enable FetchHook
  • FetchHook.cpp: Use callWithThis for Promise method calls and improve response body extraction logic
  • XHRHook.cpp: Add Fetch request detection and collaboration logic
  • NetworkGlobals.h/cpp: Add global variables for Fetch request tracking

Testing

  • ✅ Response body from Fetch requests is extracted correctly
  • Network.getResponseBody returns the correct response body
  • ✅ Promise chain works correctly
  • ✅ Fetch and XHR requests are not tracked redundantly
  • ✅ Fetch response detection that was impossible with XHR hook alone now works correctly

Related Issues

Fixes the issue where response bodies from React Native network requests were not displayed in the network tab

ohah added 2 commits January 17, 2026 23:36
- Check if client is React Native Inspector before handling Network.getResponseBody
- For RN Inspector clients, forward request to native instead of handling in Rust server
- For regular clients (e.g., Reactotron), continue handling in Rust server response_bodies
- This allows RN Inspector to retrieve response body from C++ g_responseData via nativeGetNetworkResponseBody
…FetchHook

- Fix text() and catch() calls to use callWithThis with proper this binding
- Fix 'Cannot read property constructor of undefined' error
- Ensure Promise chain works correctly with proper context binding

This fixes the issue where response body extraction failed due to
incorrect this context when calling Promise methods.
@ohah ohah requested a review from Copilot January 18, 2026 09:05
@ohah ohah self-assigned this Jan 18, 2026
@ohah ohah added the bug Something isn't working label Jan 18, 2026
@github-actions
Copy link

github-actions bot commented Jan 18, 2026

📊 Test Coverage Report - React Native Inspector

Summary

Metric Coverage
Functions 75.54%
Lines 62.25%

File Coverage

Click to expand
File Functions Lines Uncovered Lines
happydom.ts 100.00% 100.00% N/A
packages/react-native-inspector/src/metro-config.cjs 100.00% 91.18% 33,35-36
packages/react-native-inspector/src/redux-devtools-extension.ts 52.17% 47.84% 109-110,120-121,123-124,126,131,146-147,158-165,168-179,189,191,196-200,314-318,365-377,388-429,440-457,478-506,514-563,578-579,628-660
packages/react-native-inspector/src/utils.ts 50.00% 10.00% 14-15,24-57

Generated by test coverage script

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

📊 Test Coverage Report - Server

Summary

Metric Coverage
Lines 8.70%
Functions 100.00%
Branches 0.00%

File Coverage

Click to expand
File Lines Functions Branches Uncovered Lines
crates/server/src/config.rs 96.19% 100.00% 0.00% 148, 153, 158, 163
crates/server/src/socket_server/message_processor.rs 65.75% 100.00% 0.00% 15, 17-21, 23-31, 33, 35, 39-44, 48-49
crates/server/src/logging.rs 31.33% 100.00% 0.00% 20-26, 28, 48-52, 56-58, 69-71, 77, 79-84, 86, 99-106, 116-123, 143, 151-158, 160-163, 165-168, 1...
crates/server/src/socket_server/mod.rs 22.16% 100.00% 0.00% 73-80, 92, 102-114, 117-129, 132, 134-136, 139-140, 143-152, 155-158, 162-165, 169-170, 173-175, ...
crates/server/src/react_native/inspector_connection.rs 3.66% 100.00% 0.00% 57-61, 63-71, 74, 76-77, 79-81, 83-93, 95-97, 100-106, 110-120, 122-130, 133-134, 137-138, 141-14...
crates/server/src/http_routes.rs 0.00% 100.00% 0.00% 17-26, 29-31, 33-34, 37-43, 46-50, 53-66, 68, 72-75, 78-81, 84, 86, 89-90, 92-96, 99-106, 111-122...
crates/server/src/lib.rs 0.00% 100.00% 0.00% 62-68, 72-79, 81-86, 88-94, 96, 99-101, 103, 107-108, 111, 114-116, 119-120, 123, 126-138, 140-14...
crates/server/src/reactotron_server/bridge.rs 0.00% 100.00% 0.00% 10-15, 17-20, 22-31, 33-36, 39, 41-48, 51-55, 58-72, 74-75, 78-85, 89-94, 96-99, 101-110, 112-115...
crates/server/src/reactotron_server/cdp_bridge/console.rs 0.00% 100.00% 0.00% 7-11, 14-19, 21, 24-26, 28-29, 31-33, 36-40, 42-45, 48-50, 54-55, 57-58, 62-64, 69-73, 75-78, 81-...
crates/server/src/reactotron_server/cdp_bridge/mod.rs 0.00% 100.00% 0.00% 14-15, 18-24, 27-33, 36, 40-41, 44-58, 62-65, 67-68, 70, 72, 76-80, 82, 84-85, 88-89
crates/server/src/reactotron_server/cdp_bridge/network.rs 0.00% 100.00% 0.00% 10-14, 18-29, 31-42, 45-50, 53-57, 60-70, 72, 75-79, 81-82, 84, 86-93, 97-108, 110-113, 115, 119-...
crates/server/src/reactotron_server/cdp_bridge/normalize.rs 0.00% 100.00% 0.00% 7-10, 12-17, 20-22, 25-27, 31, 33-35, 38, 42-44, 46, 49, 55-63, 65, 67, 71, 73, 75-80, 83-85, 88-...
crates/server/src/reactotron_server/handler.rs 0.00% 100.00% 0.00% 28-36, 38-50, 52-53, 55-57, 60-62, 65-69, 71, 74-88, 90-91, 93-94, 96-104, 109-110, 113-116, 118-...
crates/server/src/reactotron_server/server.rs 0.00% 100.00% 0.00% 17-24, 27-31, 34-37, 40-43
crates/server/src/server.rs 0.00% 100.00% 0.00% 16-20, 23-25, 30-34, 36, 39-43, 46-61, 64-90, 93, 95-106, 109-116, 121-122, 124-126, 128-130, 135...
crates/server/src/socket_server/client_handler.rs 0.00% 100.00% 0.00% 14-23, 25-26, 28-36, 39-53, 60-72, 74, 77-86, 89-100, 102, 105-109, 111-121, 125-133, 136-145, 14...
crates/server/src/socket_server/devtools_handler.rs 0.00% 100.00% 0.00% 14-32, 34-35, 38-39, 41-45, 48-49, 54-61, 63-76, 78, 80-83, 85, 87, 90-99, 105-126, 129, 131-132,...
crates/server/src/socket_server/react_native_handler.rs 0.00% 100.00% 0.00% 16-25, 27-28, 31-37, 40-42, 45-47, 49-59, 62-74, 76, 79-86, 88-96, 99-102, 104-105, 107-110, 112-...

Generated by Rust test coverage script (cargo-llvm-cov)

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

Integration Tests

1 tests   1 ✅  21s ⏱️
1 suites  0 💤
1 files    0 ❌

Results for commit f974c8f.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

📊 Test Results

✅ Test Status: PASSED

📸 Screenshots

Screenshots are available as artifacts. Download them here.

Artifact name: playwright-screenshots

Screenshot files
  1. test-client-rn-2.png (test-client-rn-2)
  2. test-client-web-1.png (test-client-web-1)
  3. test-client-web-2.png (test-client-web-2)
  4. test-client-rn-1.png (test-client-rn-1)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Promise method calls in React Native Inspector's FetchHook by using proper this binding through callWithThis instead of call. It re-enables FetchHook to work alongside XHRHook for proper response body extraction from React Native fetch requests.

Changes:

  • Changed Promise method calls (clone(), text(), then(), catch()) to use callWithThis for proper context binding
  • Re-enabled FetchHook and implemented collaboration with XHRHook using global flags
  • Added request forwarding logic in Rust server to differentiate React Native Inspector from other clients

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/react-native-inspector/cpp/network/FetchHook.cpp Fixed Promise method calls to use callWithThis, added fetch request tracking flags, improved response body extraction with pre-extraction fallback
packages/react-native-inspector/cpp/network/XHRHook.cpp Added fetch request detection logic, prevented duplicate event transmission for fetch requests, improved collaboration with FetchHook
packages/react-native-inspector/cpp/network/NetworkGlobals.h Added global variables for fetch request tracking (g_isFetchRequestActive, g_activeFetchRequestId, g_fetchRequestMutex)
packages/react-native-inspector/cpp/network/NetworkGlobals.cpp Implemented global variables for fetch request tracking
packages/react-native-inspector/cpp/NetworkHook.cpp Re-enabled FetchHook alongside XHRHook
crates/server/src/socket_server/devtools_handler.rs Added logic to detect React Native Inspector clients and forward Network.getResponseBody requests to native code

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add documentation comment for g_activeFetchRequestId thread safety
- Remove unnecessary dummy hookedFetch initialization
- Fix race condition by keeping flag active until Promise resolution
- Clear flag in Promise handlers (onFulfilled/onRejected) instead of immediately
- Add check to ensure firstPromise is valid before returning
- Remove duplicate requestId assignment in XHRHook
@github-actions
Copy link

github-actions bot commented Jan 18, 2026

📱 Maestro Android Test Results

PASSED

Maestro Android tests have completed. Check the workflow run for details.

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

📱 Maestro iOS Test Results

PASSED

Maestro iOS tests have completed. Check the workflow run for details.

@ohah ohah merged commit fbc47ca into main Jan 18, 2026
20 checks passed
@ohah ohah deleted the fix/react-native-fetch-interceptor branch January 18, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants