Skip to content

Remove Error event listener eagerly instead of using depth count #10296

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

Merged
merged 1 commit into from
Jul 27, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions src/renderers/shared/utils/ReactErrorUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const ReactErrorUtils = {
/**
* Call a function while guarding against errors that happens within it.
* Returns an error if it throws, otherwise null.
*
*
* In production, this is implemented using a try-catch. The reason we don't
* use a try-catch directly is so that we can swap out a different
* implementation in DEV mode.
Expand Down Expand Up @@ -160,7 +160,6 @@ if (__DEV__) {
typeof document.createEvent === 'function'
) {
const fakeNode = document.createElement('react');
let depth = 0;

const invokeGuardedCallbackDev = function(
name,
Expand All @@ -186,6 +185,11 @@ if (__DEV__) {
// call the user-provided callback.
const funcArgs = Array.prototype.slice.call(arguments, 3);
function callCallback() {
// We immediately remove the callback from event listeners so that
// nested `invokeGuardedCallback` calls do not clash. Otherwise, a
// nested call would trigger the fake event handlers of any call higher
// in the stack.
fakeNode.removeEventListener(evtType, callCallback, false);
func.apply(context, funcArgs);
didError = false;
}
Expand All @@ -210,12 +214,8 @@ if (__DEV__) {
didSetError = true;
}

// Create a fake event type. We add `depth` to the event name so that
// nested `invokeGuardedCallback` calls do not clash. Otherwise, a nested
// call would trigger the fake event handlers of any call higher in
// the stack.
depth++;
const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`;
// Create a fake event type.
const evtType = `react-${name ? name : 'invokeguardedcallback'}`;

// Attach our event handlers
window.addEventListener('error', onError);
Expand Down Expand Up @@ -249,14 +249,7 @@ if (__DEV__) {
}

// Remove our event listeners
fakeNode.removeEventListener(evtType, callCallback, false);
window.removeEventListener('error', onError);

// Decrement the depth. This isn't strictly necessary, because we could
// just keep incrementing the number; the only requirement is that no two
// calls to `invokeGuardedCallback` use the same event type at the same
// time. But this does prevent `depth` from increasing boundlessly.
depth--;
};

invokeGuardedCallback = invokeGuardedCallbackDev;
Expand Down