Fix symbolication on stack trace with whatwg-fetch as a dependency

Summary:
This PR provides a workaround for issue #9605 which affects projects which directly or indirectly require `whatwg-fetch`. At that point, all symbolication on stack trace errors fails due to a circular require caused by RN's lazy loading of `fetch`, which results in `fetch` becoming `undefined`.

The workaround is simple: we postpone requiring `fetch` until the first `symbolicateStackTrace` call, at which point we can be certain `fetch` is properly exported. It is then cached for future use.

No tests have been added since, apparently, this module did not have any tests to begin with. Manual tests were performed on a regular project (not including `whatwg-fetch` externally) and a project that has direct and indirect includes for `whatwg-fetch`.
Closes https://github.com/facebook/react-native/pull/10247

Differential Revision: D4175835

Pulled By: hramos

fbshipit-source-id: d849a5874373e76f166ea6ab23f0f888792d1aef
This commit is contained in:
Hilke Heremans 2016-11-14 09:09:34 -08:00 committed by Facebook Github Bot
parent 13aba82a2b
commit be5e300abf
1 changed files with 18 additions and 1 deletions

View File

@ -14,7 +14,9 @@
const getDevServer = require('getDevServer');
const {SourceCode} = require('NativeModules');
const {fetch} = require('fetch');
// Avoid requiring fetch on load of this module; see symbolicateStackTrace
let fetch;
import type {StackFrame} from 'parseErrorStack';
@ -23,6 +25,21 @@ function isSourcedFromDisk(sourcePath: string): boolean {
}
async function symbolicateStackTrace(stack: Array<StackFrame>): Promise<Array<StackFrame>> {
// RN currently lazy loads whatwg-fetch using a custom fetch module, which,
// when called for the first time, requires and re-exports 'whatwg-fetch'.
// However, when a dependency of the project tries to require whatwg-fetch
// either directly or indirectly, whatwg-fetch is required before
// RN can lazy load whatwg-fetch. As whatwg-fetch checks
// for a fetch polyfill before loading, it will in turn try to load
// RN's fetch module, which immediately tries to import whatwg-fetch AGAIN.
// This causes a circular require which results in RN's fetch module
// exporting fetch as 'undefined'.
// The fix below postpones trying to load fetch until the first call to symbolicateStackTrace.
// At that time, we will have either global.fetch (whatwg-fetch) or RN's fetch.
if (!fetch) {
fetch = global.fetch || require('fetch').fetch;
}
const devServer = getDevServer();
if (!devServer.bundleLoadedFromServer) {
throw new Error('Bundle was not loaded from the packager');