Skip to content

Commit f63058b

Browse files
author
Ives van Hoorne
committed
Fix error detection for child components
1 parent 96f0448 commit f63058b

File tree

3 files changed

+55
-21
lines changed

3 files changed

+55
-21
lines changed

src/sandbox/errors/raw-react-component-error.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
export default class RawReactComponentError extends Error {
2-
constructor(importedModule) {
2+
constructor(mainModule, importedModule) {
33
super();
44

55
this.payload = {
66
importedModuleId: importedModule.id,
77
};
8+
this.module = mainModule;
89
}
910

1011
type = 'raw-react-component-import';

src/sandbox/eval/js/error-transformer.js

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
/* @flow */
22
import type { Module } from 'common/types';
3-
import RawReactComponentError from '../../errors/raw-react-component-error';
4-
3+
import type { ModuleCacheModule } from './';
54
import {
65
hasReact,
76
getMode,
87
} from 'app/store/entities/sandboxes/modules/utils/get-type';
98

10-
const getModule = (modules: Array<Module>, id: string): ?Module =>
11-
modules.find(m => m.id === id);
9+
import RawReactComponentError from '../../errors/raw-react-component-error';
1210

13-
const reactRegex = /import.*from\s['|"]react['|"]/;
1411
/**
1512
* This error happens when a user tries to use a React component that's imported
1613
* from a raw file. In that case the React component will be a string and thus
@@ -20,17 +17,39 @@ function buildRawReactComponentError(
2017
error: Error,
2118
module: Module,
2219
modules: Array<Module>,
20+
moduleCache: Map<string, ModuleCacheModule>,
2321
requires: Array<string>,
2422
) {
25-
const rawModuleUsingReact = requires
26-
.map(id => getModule(modules, id))
27-
.filter(x => x)
28-
.filter(m => hasReact(m.code || ''))
29-
.find(m => getMode(m) === 'raw');
23+
const requiredModules = requires
24+
.map(id => modules.find(m => m.id === id))
25+
.filter(x => x != null)
26+
.filter(m => hasReact(m.code || ''));
3027

31-
if (!rawModuleUsingReact) return error;
28+
const rawModuleUsingReact = requiredModules.find(m => getMode(m) === 'raw');
3229

33-
return new RawReactComponentError(rawModuleUsingReact);
30+
// Cannot find a raw module, but a child react component could render a raw
31+
// component, let's find out!
32+
if (!rawModuleUsingReact) {
33+
const childRawModuleError = requiredModules
34+
.map(m => moduleCache.get(m.id))
35+
.filter(x => x != null)
36+
.map(
37+
m =>
38+
m &&
39+
buildRawReactComponentError(
40+
error,
41+
m.module,
42+
modules,
43+
moduleCache,
44+
m.requires,
45+
),
46+
)
47+
.find(m => m);
48+
49+
if (childRawModuleError) return childRawModuleError;
50+
} else {
51+
return new RawReactComponentError(module, rawModuleUsingReact);
52+
}
3453
}
3554

3655
/**
@@ -44,15 +63,18 @@ export default function transformError(
4463
error: Error,
4564
module: Module,
4665
modules: Array<Module>,
66+
moduleCache: Map<string, ModuleCacheModule>,
4767
requires: Array<string>,
4868
) {
4969
if (error.message.startsWith('Invalid tag: import React')) {
50-
const newError = buildRawReactComponentError(
51-
error,
52-
module,
53-
modules,
54-
requires,
55-
);
70+
const newError =
71+
buildRawReactComponentError(
72+
error,
73+
module,
74+
modules,
75+
moduleCache,
76+
requires,
77+
) || error;
5678
newError.message = error.message;
5779
return newError;
5880
}

src/sandbox/eval/js/index.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import resolveDependency from './dependency-resolver';
99
import getBabelConfig from './babel-parser';
1010
import transformError from './error-transformer';
1111

12-
const moduleCache = new Map();
12+
export type ModuleCacheModule = {
13+
requires: Array<string>,
14+
module: Module,
15+
exports: Object,
16+
};
17+
const moduleCache: Map<string, ModuleCacheModule> = new Map();
1318

1419
export function clearCache() {
1520
moduleCache.clear();
@@ -145,7 +150,13 @@ export default function evaluateJS(
145150

146151
e.module = e.module || mainModule;
147152

148-
const newError = transformError(e, e.module, modules, requires);
153+
const newError = transformError(
154+
e,
155+
e.module,
156+
modules,
157+
moduleCache,
158+
requires,
159+
);
149160
throw newError;
150161
}
151162
}

0 commit comments

Comments
 (0)