Update error transform to allow excluding errors inside subexpressions like ternaries (#24693)
* Update error transform to allow excluding errors inside subexpressions like ternaries * make leadingcomments aggregation walk the expression stack
Josh Story committed
Jun 8, 2022 at 16:59 UTC
9e3b772b8cabbd8cadc7522ebe3dde3279e79d9e
3 files changed
+86
-1
scripts/error-codes/__tests__/__snapshots__/transform-error-messages.js.snap
+24
@@ -1,10 +1,34 @@
1
// Jest Snapshot v1, https://goo.gl/fbAQLP
2
3
+exports[`error transform handles deeply nested expressions 1`] = `
4
+"var val = (a, (b, // eslint-disable-next-line react-internal/prod-error-codes
5
+new Error('foo')));"
6
+`;
7
+
8
+exports[`error transform handles deeply nested expressions 2`] = `
9
+"var val = (a, ( // eslint-disable-next-line react-internal/prod-error-codes
10
+b, new Error('foo')));"
11
+`;
12
+
13
exports[`error transform handles escaped backticks in template string 1`] = `
14
"import _formatProdErrorMessage from \\"shared/formatProdErrorMessage\\";
15
Error(_formatProdErrorMessage(231, listener, type));"
16
`;
17
18
+exports[`error transform handles ignoring errors that are comment-excluded inside ternary expressions 1`] = `
19
+"/*! FIXME (minify-errors-in-prod): Unminified error message in production build!*/
20
+
21
+/*! <expected-error-format>\\"bar\\"</expected-error-format>*/
22
+var val = someBool ? //eslint-disable-next-line react-internal/prod-error-codes
23
+new Error('foo') : someOtherBool ? new Error('bar') : //eslint-disable-next-line react-internal/prod-error-codes
24
+new Error('baz');"
25
+`;
26
+
27
+exports[`error transform handles ignoring errors that are comment-excluded outside ternary expressions 1`] = `
28
+"//eslint-disable-next-line react-internal/prod-error-codes
29
+var val = someBool ? new Error('foo') : someOtherBool ? new Error('bar') : new Error('baz');"
30
+`;
31
+
32
exports[`error transform should not touch other calls or new expressions 1`] = `
33
"new NotAnError();
34
NotAnError();"
scripts/error-codes/__tests__/transform-error-messages.js
+48
@@ -106,6 +106,54 @@ new Error(\`Expected \${foo} target to \` + \`be an array; got \${bar}\`);
106
expect(
107
transform(`
108
new Error(\`Expected \\\`\$\{listener\}\\\` listener to be a function, instead got a value of \\\`\$\{type\}\\\` type.\`);
109
+`)
110
+ ).toMatchSnapshot();
111
+ });
112
+
113
+ it('handles ignoring errors that are comment-excluded inside ternary expressions', () => {
114
+ expect(
115
+ transform(`
116
+let val = someBool
117
+ ? //eslint-disable-next-line react-internal/prod-error-codes
118
+ new Error('foo')
119
+ : someOtherBool
120
+ ? new Error('bar')
121
+ : //eslint-disable-next-line react-internal/prod-error-codes
122
+ new Error('baz');
123
+`)
124
+ ).toMatchSnapshot();
125
+ });
126
+
127
+ it('handles ignoring errors that are comment-excluded outside ternary expressions', () => {
128
+ expect(
129
+ transform(`
130
+//eslint-disable-next-line react-internal/prod-error-codes
131
+let val = someBool
132
+ ? new Error('foo')
133
+ : someOtherBool
134
+ ? new Error('bar')
135
+ : new Error('baz');
136
+`)
137
+ ).toMatchSnapshot();
138
+ });
139
+
140
+ it('handles deeply nested expressions', () => {
141
+ expect(
142
+ transform(`
143
+let val =
144
+ (a,
145
+ (b,
146
+ // eslint-disable-next-line react-internal/prod-error-codes
147
+ new Error('foo')));
148
+`)
149
+ ).toMatchSnapshot();
150
+
151
+ expect(
152
+ transform(`
153
+let val =
154
+ (a,
155
+ // eslint-disable-next-line react-internal/prod-error-codes
156
+ (b, new Error('foo')));
157
`)
158
).toMatchSnapshot();
159
});
scripts/error-codes/transform-error-messages.js
+14
-1
@@ -62,8 +62,21 @@ module.exports = function(babel) {
62
// throw Error(`A ${adj} message that contains ${noun}`);
63
// }
64
65
+ let leadingComments = [];
66
+
67
const statementParent = path.getStatementParent();
66
- const leadingComments = statementParent.node.leadingComments;
68
+ let nextPath = path;
69
+ while (true) {
70
+ let nextNode = nextPath.node;
71
+ if (nextNode.leadingComments) {
72
+ leadingComments.push(...nextNode.leadingComments);
73
+ }
74
+ if (nextPath === statementParent) {
75
+ break;
76
+ }
77
+ nextPath = nextPath.parentPath;
78
+ }
79
+
80
if (leadingComments !== undefined) {
81
for (let i = 0; i < leadingComments.length; i++) {
82
// TODO: Since this only detects one of many ways to disable a lint