@samitouri / QOS-React-2 / commits / d6a2c669d2

Fix ReactErrorUtils injection (#9247)

Dan Abramov committed Mar 23, 2017 at 19:13 UTC d6a2c669d22e0bf0bc839493b863673df09c99c9
1 file changed +64 -66
src/renderers/shared/utils/ReactErrorUtils.js
+64 -66
@@ -16,6 +16,66 @@ const invariant = require('invariant');
16
17 let caughtError = null;
18
19 +let invokeGuardedCallback = function(name, func, context, a, b, c, d, e, f) {
20 + const funcArgs = Array.prototype.slice.call(arguments, 3);
21 + try {
22 + func.apply(context, funcArgs);
23 + } catch (error) {
24 + return error;
25 + }
26 + return null;
27 +};
28 +
29 +if (__DEV__) {
30 + /**
31 + * To help development we can get better devtools integration by simulating a
32 + * real browser event.
33 + */
34 + if (
35 + typeof window !== 'undefined' &&
36 + typeof window.dispatchEvent === 'function' &&
37 + typeof document !== 'undefined' &&
38 + typeof document.createEvent === 'function'
39 + ) {
40 + const fakeNode = document.createElement('react');
41 + let depth = 0;
42 +
43 + invokeGuardedCallback = function(name, func, context, a, b, c, d, e, f) {
44 + depth++;
45 + const thisDepth = depth;
46 + const funcArgs = Array.prototype.slice.call(arguments, 3);
47 + const boundFunc = function() {
48 + func.apply(context, funcArgs);
49 + };
50 + let fakeEventError = null;
51 + const onFakeEventError = function(event) {
52 + // Don't capture nested errors
53 + if (depth === thisDepth) {
54 + fakeEventError = event.error;
55 + }
56 + };
57 + const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`;
58 + window.addEventListener('error', onFakeEventError);
59 + fakeNode.addEventListener(evtType, boundFunc, false);
60 + const evt = document.createEvent('Event');
61 + evt.initEvent(evtType, false, false);
62 + fakeNode.dispatchEvent(evt);
63 + fakeNode.removeEventListener(evtType, boundFunc, false);
64 + window.removeEventListener('error', onFakeEventError);
65 + depth--;
66 + return fakeEventError;
67 + };
68 + }
69 +}
70 +
71 +let rethrowCaughtError = function() {
72 + if (caughtError) {
73 + const error = caughtError;
74 + caughtError = null;
75 + throw error;
76 + }
77 +};
78 +
79 /**
80 * Call a function while guarding against errors that happens within it.
81 * Returns an error if it throws, otherwise null.
@@ -36,8 +96,8 @@ const ReactErrorUtils = {
96 typeof injectedErrorUtils.rethrowCaughtError === 'function',
97 'Injected rethrowCaughtError() must be a function.',
98 );
39 - ReactErrorUtils.invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback;
40 - ReactErrorUtils.rethrowCaughtError = injectedErrorUtils.rethrowCaughtError;
99 + invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback;
100 + rethrowCaughtError = injectedErrorUtils.rethrowCaughtError;
101 },
102 },
103
@@ -52,13 +112,7 @@ const ReactErrorUtils = {
112 e: E,
113 f: F,
114 ): Error | null {
55 - const funcArgs = Array.prototype.slice.call(arguments, 3);
56 - try {
57 - func.apply(context, funcArgs);
58 - } catch (error) {
59 - return error;
60 - }
61 - return null;
115 + return invokeGuardedCallback.apply(this, arguments);
116 },
117
118 /**
@@ -92,64 +146,8 @@ const ReactErrorUtils = {
146 * we will rethrow to be handled by the top level error handler.
147 */
148 rethrowCaughtError: function() {
95 - if (caughtError) {
96 - const error = caughtError;
97 - caughtError = null;
98 - throw error;
99 - }
149 + return rethrowCaughtError.apply(this, arguments);
150 },
151 };
152
103 -if (__DEV__) {
104 - /**
105 - * To help development we can get better devtools integration by simulating a
106 - * real browser event.
107 - */
108 - if (
109 - typeof window !== 'undefined' &&
110 - typeof window.dispatchEvent === 'function' &&
111 - typeof document !== 'undefined' &&
112 - typeof document.createEvent === 'function'
113 - ) {
114 - const fakeNode = document.createElement('react');
115 - let depth = 0;
116 -
117 - ReactErrorUtils.invokeGuardedCallback = function(
118 - name,
119 - func,
120 - context,
121 - a,
122 - b,
123 - c,
124 - d,
125 - e,
126 - f,
127 - ) {
128 - depth++;
129 - const thisDepth = depth;
130 - const funcArgs = Array.prototype.slice.call(arguments, 3);
131 - const boundFunc = function() {
132 - func.apply(context, funcArgs);
133 - };
134 - let fakeEventError = null;
135 - const onFakeEventError = function(event) {
136 - // Don't capture nested errors
137 - if (depth === thisDepth) {
138 - fakeEventError = event.error;
139 - }
140 - };
141 - const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`;
142 - window.addEventListener('error', onFakeEventError);
143 - fakeNode.addEventListener(evtType, boundFunc, false);
144 - const evt = document.createEvent('Event');
145 - evt.initEvent(evtType, false, false);
146 - fakeNode.dispatchEvent(evt);
147 - fakeNode.removeEventListener(evtType, boundFunc, false);
148 - window.removeEventListener('error', onFakeEventError);
149 - depth--;
150 - return fakeEventError;
151 - };
152 - }
153 -}
154 -
153 module.exports = ReactErrorUtils;