Skip to content

Commit 94995fd

Browse files
vzaidmanmeta-codesync[bot]
authored andcommitted
add rules to prefer Error objects to be thrown and rejected (facebook#54229)
Summary: Pull Request resolved: facebook#54229 Changelog: [General][Added] Added eslint rule to warn when a non-error is being thrown from a function or rejected for a promise. Reviewed By: huntie Differential Revision: D85237916 fbshipit-source-id: e0e4fbc6b4620a19be1959d3953856c7e44ad4e0
1 parent 9cadfe6 commit 94995fd

File tree

7 files changed

+20
-9
lines changed

7 files changed

+20
-9
lines changed

.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ module.exports = {
3535
// Flow handles these checks for us, so they aren't required
3636
'no-undef': 'off',
3737
'no-unreachable': 'off',
38+
// Throwing from function or rejecting promises with non-error values could result in unclear error stack traces and lead to harder debugging
39+
'prefer-promise-reject-errors': 'error',
40+
'no-throw-literal': 'error',
3841
},
3942
},
4043
{

packages/react-native/Libraries/Debugging/DebuggingOverlayRegistry.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,9 @@ class DebuggingOverlayRegistry {
332332
instance.measure((x, y, width, height, left, top) => {
333333
// measure can execute callback without any values provided to signal error.
334334
if (left == null || top == null || width == null || height == null) {
335-
reject('Unexpectedly failed to call measure on an instance.');
335+
reject(
336+
new Error('Unexpectedly failed to call measure on an instance.'),
337+
);
336338
}
337339

338340
resolve({
@@ -480,7 +482,11 @@ class DebuggingOverlayRegistry {
480482
width == null ||
481483
height == null
482484
) {
483-
reject('Unexpectedly failed to call measure on an instance.');
485+
reject(
486+
new Error(
487+
'Unexpectedly failed to call measure on an instance.',
488+
),
489+
);
484490
}
485491

486492
resolve({x: left, y: top, width, height});

packages/react-native/Libraries/NativeComponent/NativeComponentRegistryUnstable.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ export function unstable_hasComponent(name: string): boolean {
2323
hasNativeComponent = global.__nativeComponentRegistry__hasComponent(name);
2424
componentNameToExists.set(name, hasNativeComponent);
2525
} else {
26-
throw `unstable_hasComponent('${name}'): Global function is not registered`;
26+
throw new Error(
27+
`unstable_hasComponent('${name}'): Global function is not registered`,
28+
);
2729
}
2830
}
2931
return hasNativeComponent;

packages/react-native/scripts/codegen/codegen-utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function getCodegen() /*: $FlowFixMe */ {
3030
RNCodegen = require('@react-native/codegen/lib/generators/RNCodegen.js');
3131
}
3232
if (!RNCodegen) {
33-
throw 'RNCodegen not found.';
33+
throw new Error('RNCodegen not found.');
3434
}
3535
return RNCodegen;
3636
}
@@ -45,7 +45,7 @@ function getCombineJSToSchema() /*: $FlowFixMe */ {
4545
combineJSToSchema = require('@react-native/codegen/lib/cli/combine/combine-js-to-schema.js');
4646
}
4747
if (!combineJSToSchema) {
48-
throw 'combine-js-to-schema not found.';
48+
throw new Error('combine-js-to-schema not found.');
4949
}
5050
return combineJSToSchema;
5151
}

packages/react-native/scripts/codegen/generate-artifacts-executor/utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const codegenLog = (text /*: string */, info /*: boolean */ = false) => {
3838
function readPkgJsonInDirectory(dir /*: string */) /*: $FlowFixMe */ {
3939
const pkgJsonPath = path.join(dir, 'package.json');
4040
if (!fs.existsSync(pkgJsonPath)) {
41-
throw `[Codegen] Error: ${pkgJsonPath} does not exist.`;
41+
throw new Error(`[Codegen] Error: ${pkgJsonPath} does not exist.`);
4242
}
4343
return JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
4444
}
@@ -174,7 +174,7 @@ function findProjectRootLibraries(
174174
}
175175

176176
if (typeof pkgJson.codegenConfig !== 'object') {
177-
throw 'The "codegenConfig" field must be an Object.';
177+
throw new Error('The "codegenConfig" field must be an Object.');
178178
}
179179

180180
return extractLibrariesFromJSON(pkgJson, projectRoot);

packages/rn-tester/NativeModuleExample/NativeScreenshotManager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ export function takeScreenshot(
3030
if (NativeModule != null) {
3131
return NativeModule.takeScreenshot(id, options);
3232
}
33-
return Promise.reject();
33+
return Promise.reject(new Error('ScreenshotManager is not defined.'));
3434
}

packages/rn-tester/js/examples/ContentURLAndroid/ContentURLAndroid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function blobToBase64(blob: Blob) {
3434
if (typeof result === 'string') {
3535
resolve(result);
3636
} else {
37-
reject('error: incompatible types');
37+
reject(new Error('error: incompatible types'));
3838
}
3939
};
4040
reader.readAsDataURL(blob);

0 commit comments

Comments
 (0)