Skip to content

Commit 7155426

Browse files
committed
Fix missing wildcardRequire and error overlay showing error boundary issues
1 parent 081e715 commit 7155426

File tree

7 files changed

+199
-93
lines changed

7 files changed

+199
-93
lines changed

packages/app/src/app/overmind/namespaces/editor/actions.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -530,14 +530,18 @@ export const previewActionReceived: Action<{
530530
severity: action.severity,
531531
type: action.type,
532532
};
533-
const module = resolveModule(
534-
error.path,
535-
state.editor.currentSandbox.modules,
536-
state.editor.currentSandbox.directories
537-
);
533+
try {
534+
const module = resolveModule(
535+
error.path,
536+
state.editor.currentSandbox.modules,
537+
state.editor.currentSandbox.directories
538+
);
538539

539-
module.errors.push(json(error));
540-
state.editor.errors.push(error);
540+
module.errors.push(json(error));
541+
state.editor.errors.push(error);
542+
} catch (e) {
543+
/* ignore, this module can be in a node_modules for example */
544+
}
541545
break;
542546
}
543547
case 'show-correction': {
@@ -551,14 +555,18 @@ export const previewActionReceived: Action<{
551555
source: action.source,
552556
severity: action.severity,
553557
};
554-
const module = resolveModule(
555-
correction.path,
556-
state.editor.currentSandbox.modules,
557-
state.editor.currentSandbox.directories
558-
);
558+
try {
559+
const module = resolveModule(
560+
correction.path,
561+
state.editor.currentSandbox.modules,
562+
state.editor.currentSandbox.directories
563+
);
559564

560-
state.editor.corrections.push(correction);
561-
module.corrections.push(json(correction));
565+
state.editor.corrections.push(correction);
566+
module.corrections.push(json(correction));
567+
} catch (e) {
568+
/* ignore, this module can be in a node_modules for example */
569+
}
562570
break;
563571
}
564572
case 'clear-errors': {

packages/app/src/sandbox/eval/transpilers/babel/worker/babel-worker.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,17 @@ async function compile(code, customConfig, path, isV7) {
359359
if (isV7) {
360360
// Force push this dependency, there are cases where it isn't included out of our control.
361361
// https://twitter.com/vigs072/status/1103005932886343680
362+
// TODO: look into this
362363
dependencies.push({
363-
type: 'direct',
364364
path: '@babel/runtime/helpers/interopRequireDefault',
365+
type: 'direct',
366+
});
367+
dependencies.push({
368+
path: '@babel/runtime/helpers/interopRequireWildcard',
369+
type: 'direct',
365370
});
366371
}
372+
367373
dependencies.forEach(dependency => {
368374
self.postMessage({
369375
type: 'add-dependency',

packages/sandbox-hooks/react-error-overlay/effects/proxyConsole.js

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
/**
22
* Copyright (c) 2015-present, Facebook, Inc.
3-
* All rights reserved.
43
*
5-
* This source code is licensed under the BSD-style license found in the
6-
* LICENSE file in the root directory of this source tree. An additional grant
7-
* of patent rights can be found in the PATENTS file in the same directory.
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
86
*/
97

108
/* @flow */
@@ -23,7 +21,7 @@ export type { ReactFrame };
2321
// We're implementing just enough to get the invalid element type warnings
2422
// to display the component stack in React 15.6+:
2523
// https://github.com/facebook/react/pull/9679
26-
/// TODO: a more comprehensive implementation.
24+
// / TODO: a more comprehensive implementation.
2725

2826
const registerReactStack = () => {
2927
if (typeof console !== 'undefined') {
@@ -44,34 +42,27 @@ const unregisterReactStack = () => {
4442
};
4543

4644
type ConsoleProxyCallback = (message: string, frames: ReactFrame[]) => void;
47-
48-
let registered = false;
4945
const permanentRegister = function proxyConsole(
5046
type: string,
5147
callback: ConsoleProxyCallback
5248
) {
53-
if (!registered) {
54-
registered = true;
55-
if (typeof console !== 'undefined') {
56-
const orig = console[type];
57-
if (typeof orig === 'function') {
58-
console[type] = function __stack_frame_overlay_proxy_console__() {
59-
try {
60-
const message = arguments[0];
61-
if (typeof message === 'string') {
62-
if (reactFrameStack.length > 0) {
63-
callback(message, reactFrameStack[reactFrameStack.length - 1]);
64-
}
65-
}
66-
} catch (err) {
67-
// Warnings must never crash. Rethrow with a clean stack.
68-
setTimeout(function() {
69-
throw err;
70-
});
49+
if (typeof console !== 'undefined') {
50+
const orig = console[type];
51+
if (typeof orig === 'function') {
52+
console[type] = function __stack_frame_overlay_proxy_console__() {
53+
try {
54+
const message = arguments[0];
55+
if (typeof message === 'string' && reactFrameStack.length > 0) {
56+
callback(message, reactFrameStack[reactFrameStack.length - 1]);
7157
}
72-
return orig.apply(this, arguments);
73-
};
74-
}
58+
} catch (err) {
59+
// Warnings must never crash. Rethrow with a clean stack.
60+
setTimeout(function() {
61+
throw err;
62+
});
63+
}
64+
return orig.apply(this, arguments);
65+
};
7566
}
7667
}
7768
};

packages/sandbox-hooks/react-error-overlay/effects/unhandledRejection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function rejectionHandler(
1919
if (e == null || e.reason == null) {
2020
return callback(new Error('Unknown'));
2121
}
22-
let { reason } = e;
22+
const { reason } = e;
2323
if (reason instanceof Error) {
2424
return callback(reason);
2525
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import {
9+
register as registerError,
10+
unregister as unregisterError,
11+
} from './effects/unhandledError';
12+
import {
13+
register as registerPromise,
14+
unregister as unregisterPromise,
15+
} from './effects/unhandledRejection';
16+
import {
17+
register as registerStackTraceLimit,
18+
unregister as unregisterStackTraceLimit,
19+
} from './effects/stackTraceLimit';
20+
import {
21+
permanentRegister as permanentRegisterConsole,
22+
registerReactStack,
23+
unregisterReactStack,
24+
} from './effects/proxyConsole';
25+
import { massage as massageWarning } from './utils/warnings';
26+
import getStackFrames from './utils/getStackFrames';
27+
28+
import type { StackFrame } from './utils/stack-frame';
29+
30+
const CONTEXT_SIZE: number = 3;
31+
32+
export type ErrorRecord = {|
33+
error: Error,
34+
unhandledRejection: boolean,
35+
contextSize: number,
36+
stackFrames: StackFrame[],
37+
|};
38+
39+
export const crashWithFrames = (crash: ErrorRecord => void) => (
40+
error: Error,
41+
unhandledRejection = false
42+
) => {
43+
getStackFrames(error, unhandledRejection, CONTEXT_SIZE)
44+
.then(stackFrames => {
45+
// SOURCE_CHANGE,
46+
if (stackFrames == null && error.name !== 'SyntaxError') {
47+
return;
48+
}
49+
crash({
50+
error,
51+
unhandledRejection,
52+
contextSize: CONTEXT_SIZE,
53+
stackFrames,
54+
});
55+
})
56+
.catch(e => {
57+
console.log('Could not get the stack frames of error:', e);
58+
});
59+
};
60+
61+
export function listenToRuntimeErrors(
62+
crash: ErrorRecord => void,
63+
filename: string = '/static/js/bundle.js'
64+
) {
65+
const crashWithFramesRunTime = crashWithFrames(crash);
66+
67+
registerError(window, error => crashWithFramesRunTime(error, false));
68+
registerPromise(window, error => crashWithFramesRunTime(error, true));
69+
registerStackTraceLimit();
70+
registerReactStack();
71+
permanentRegisterConsole('error', (warning, stack) => {
72+
const data = massageWarning(warning, stack);
73+
crashWithFramesRunTime(
74+
// $FlowFixMe
75+
{
76+
message: data.message,
77+
stack: data.stack,
78+
__unmap_source: filename,
79+
},
80+
false
81+
);
82+
});
83+
84+
return function stopListening() {
85+
unregisterStackTraceLimit();
86+
unregisterPromise(window);
87+
unregisterError(window);
88+
unregisterReactStack();
89+
};
90+
}

packages/sandbox-hooks/react-error-overlay/overlay.js

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,7 @@
1111
import { transformError } from 'codesandbox-api';
1212
import { getCurrentManager } from 'app/src/sandbox/compile';
1313

14-
import {
15-
register as registerError,
16-
unregister as unregisterError,
17-
} from './effects/unhandledError';
18-
import {
19-
register as registerPromise,
20-
unregister as unregisterPromise,
21-
} from './effects/unhandledRejection';
22-
import {
23-
register as registerShortcuts,
24-
unregister as unregisterShortcuts,
25-
handler as keyEventHandler,
26-
SHORTCUT_ESCAPE,
27-
SHORTCUT_LEFT,
28-
SHORTCUT_RIGHT,
29-
} from './effects/shortcuts';
30-
import {
31-
register as registerStackTraceLimit,
32-
unregister as unregisterStackTraceLimit,
33-
} from './effects/stackTraceLimit';
34-
import {
35-
permanentRegister as permanentRegisterConsole,
36-
registerReactStack,
37-
unregisterReactStack,
38-
} from './effects/proxyConsole';
39-
import { massage as massageWarning } from './utils/warnings';
14+
import { listenToRuntimeErrors } from './listenToRuntimeErrors';
4015

4116
import {
4217
consume as consumeError,
@@ -204,7 +179,7 @@ function transformErrors() {
204179
}
205180
});
206181

207-
let tModule = errRef.error.tModule;
182+
let { tModule } = errRef.error;
208183

209184
if (!tModule && relevantFrame) {
210185
const fileName =
@@ -294,38 +269,25 @@ function shortcutHandler(type: string) {
294269
break;
295270
}
296271
default: {
297-
//TODO: this
272+
// TODO: this
298273
break;
299274
}
300275
}
301276
}
302277

278+
let listenToRuntimeErrorsUnmounter;
279+
303280
function inject() {
304-
registerError(window, error => crash(error));
305-
registerPromise(window, error => crash(error, true));
306-
registerShortcuts(window, shortcutHandler);
307-
registerStackTraceLimit();
308-
309-
registerReactStack();
310-
permanentRegisterConsole('error', (warning, stack) => {
311-
const data = massageWarning(warning, stack);
312-
crash(
313-
// $FlowFixMe
314-
{
315-
message: data.message,
316-
stack: data.stack,
317-
},
318-
false
319-
);
281+
listenToRuntimeErrorsUnmounter = listenToRuntimeErrors(error => {
282+
console.log('what the matter', error);
283+
crash(error.error);
320284
});
321285
}
322286

323287
function uninject() {
324-
unregisterStackTraceLimit();
325-
unregisterShortcuts(window);
326-
unregisterPromise(window);
327-
unregisterError(window);
328-
unregisterReactStack();
288+
if (listenToRuntimeErrorsUnmounter) {
289+
listenToRuntimeErrorsUnmounter();
290+
}
329291
unmount();
330292
}
331293

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
/* @flow */
9+
import type { StackFrame } from './stack-frame';
10+
import { parse } from './parser';
11+
import { map } from './mapper';
12+
import { unmap } from './unmapper';
13+
14+
function getStackFrames(
15+
error: Error,
16+
unhandledRejection: boolean = false,
17+
contextSize: number = 3
18+
): Promise<StackFrame[] | null> {
19+
const parsedFrames = parse(error);
20+
let enhancedFramesPromise;
21+
// $FlowFixMe
22+
if (error.__unmap_source) {
23+
enhancedFramesPromise = unmap(
24+
// $FlowFixMe
25+
error.__unmap_source,
26+
parsedFrames,
27+
contextSize
28+
);
29+
} else {
30+
enhancedFramesPromise = map(parsedFrames, contextSize);
31+
}
32+
return enhancedFramesPromise.then(enhancedFrames => {
33+
if (
34+
enhancedFrames
35+
.map(f => f._originalFileName)
36+
.filter(f => f != null && f.indexOf('node_modules') === -1).length === 0
37+
) {
38+
return null;
39+
}
40+
return enhancedFrames.filter(
41+
({ functionName }) =>
42+
functionName == null ||
43+
functionName.indexOf('__stack_frame_overlay_proxy_console__') === -1
44+
);
45+
});
46+
}
47+
48+
export default getStackFrames;
49+
export { getStackFrames };

0 commit comments

Comments
 (0)