diff --git a/docs/rules/throw-new-error.md b/docs/rules/throw-new-error.md index 33e60fd883..72d2423d42 100644 --- a/docs/rules/throw-new-error.md +++ b/docs/rules/throw-new-error.md @@ -1,4 +1,4 @@ -# Require `new` when throwing an error +# Require `new` when creating an error 💼 This rule is enabled in the ✅ `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs). @@ -12,7 +12,7 @@ While it's possible to create a new error without using the `new` keyword, it's ## Fail ```js -throw Error(); +const error = Error('unicorn'); ``` ```js @@ -20,13 +20,13 @@ throw TypeError('unicorn'); ``` ```js -throw lib.TypeError(); +throw lib.TypeError('unicorn'); ``` ## Pass ```js -throw new Error(); +const error = new Error('unicorn'); ``` ```js @@ -34,5 +34,5 @@ throw new TypeError('unicorn'); ``` ```js -throw new lib.TypeError(); +throw new lib.TypeError('unicorn'); ``` diff --git a/readme.md b/readme.md index 9cd69cf9a6..e25135c52b 100644 --- a/readme.md +++ b/readme.md @@ -223,7 +223,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c | [switch-case-braces](docs/rules/switch-case-braces.md) | Enforce consistent brace style for `case` clauses. | ✅ | 🔧 | | | [template-indent](docs/rules/template-indent.md) | Fix whitespace-insensitive template indentation. | ✅ | 🔧 | | | [text-encoding-identifier-case](docs/rules/text-encoding-identifier-case.md) | Enforce consistent case for text encoding identifiers. | ✅ | 🔧 | 💡 | -| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when throwing an error. | ✅ | 🔧 | | +| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when creating an error. | ✅ | 🔧 | | diff --git a/rules/throw-new-error.js b/rules/throw-new-error.js index c8fb4476f3..2815f98691 100644 --- a/rules/throw-new-error.js +++ b/rules/throw-new-error.js @@ -3,7 +3,7 @@ const {switchCallExpressionToNewExpression} = require('./fix/index.js'); const messageId = 'throw-new-error'; const messages = { - [messageId]: 'Use `new` when throwing an error.', + [messageId]: 'Use `new` when creating an error.', }; const customError = /^(?:[A-Z][\da-z]*)*Error$/; @@ -11,13 +11,6 @@ const customError = /^(?:[A-Z][\da-z]*)*Error$/; /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ CallExpression(node) { - if (!( - node.parent.type === 'ThrowStatement' - && node.parent.argument === node - )) { - return; - } - const {callee} = node; if (!( (callee.type === 'Identifier' && customError.test(callee.name)) @@ -45,7 +38,7 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Require `new` when throwing an error.', + description: 'Require `new` when creating an error.', }, fixable: 'code', messages, diff --git a/test/error-message.mjs b/test/error-message.mjs index 86a2d7f0d5..f4eb5ba101 100644 --- a/test/error-message.mjs +++ b/test/error-message.mjs @@ -69,6 +69,7 @@ test.snapshot({ 'throw new Error({foo: 0}.foo)', 'throw new Error(lineNumber=2)', 'const error = new RangeError;', + 'throw Object.assign(new Error(), {foo})', ], }); diff --git a/test/snapshots/error-message.mjs.md b/test/snapshots/error-message.mjs.md index 11e4c907ce..57b3116ac7 100644 --- a/test/snapshots/error-message.mjs.md +++ b/test/snapshots/error-message.mjs.md @@ -286,6 +286,21 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^ Pass a message to the \`RangeError\` constructor.␊ ` +## invalid(19): throw Object.assign(new Error(), {foo}) + +> Input + + `␊ + 1 | throw Object.assign(new Error(), {foo})␊ + ` + +> Error 1/1 + + `␊ + > 1 | throw Object.assign(new Error(), {foo})␊ + | ^^^^^^^^^^^ Pass a message to the \`Error\` constructor.␊ + ` + ## invalid(1): new AggregateError(errors) > Input diff --git a/test/snapshots/error-message.mjs.snap b/test/snapshots/error-message.mjs.snap index 60ff9c14e0..0345896652 100644 Binary files a/test/snapshots/error-message.mjs.snap and b/test/snapshots/error-message.mjs.snap differ diff --git a/test/snapshots/throw-new-error.mjs.md b/test/snapshots/throw-new-error.mjs.md index 5de5a7da48..8e36df5d8e 100644 --- a/test/snapshots/throw-new-error.mjs.md +++ b/test/snapshots/throw-new-error.mjs.md @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw Error()␊ - | ^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(2): throw (Error)() @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (Error)()␊ - | ^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(3): throw lib.Error() @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib.Error()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(4): throw lib.mod.Error() @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib.mod.Error()␊ - | ^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(5): throw lib[mod].Error() @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib[mod].Error()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(6): throw (lib.mod).Error() @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (lib.mod).Error()␊ - | ^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(7): throw Error('foo') @@ -148,7 +148,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw Error('foo')␊ - | ^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(8): throw CustomError('foo') @@ -169,7 +169,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw CustomError('foo')␊ - | ^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(9): throw FooBarBazError('foo') @@ -190,7 +190,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw FooBarBazError('foo')␊ - | ^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(10): throw ABCError('foo') @@ -211,7 +211,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw ABCError('foo')␊ - | ^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(11): throw Abc3Error('foo') @@ -232,7 +232,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw Abc3Error('foo')␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(12): throw TypeError() @@ -253,7 +253,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw TypeError()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(13): throw EvalError() @@ -274,7 +274,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw EvalError()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(14): throw RangeError() @@ -295,7 +295,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw RangeError()␊ - | ^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(15): throw ReferenceError() @@ -316,7 +316,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw ReferenceError()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(16): throw SyntaxError() @@ -337,7 +337,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw SyntaxError()␊ - | ^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(17): throw URIError() @@ -358,7 +358,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw URIError()␊ - | ^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(18): throw (( URIError() )) @@ -379,7 +379,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( URIError() ))␊ - | ^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(19): throw (( URIError ))() @@ -400,7 +400,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( URIError ))()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(20): throw getGlobalThis().Error() @@ -421,7 +421,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw getGlobalThis().Error()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(21): throw utils.getGlobalThis().Error() @@ -442,7 +442,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw utils.getGlobalThis().Error()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(22): throw (( getGlobalThis().Error ))() @@ -463,5 +463,74 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( getGlobalThis().Error ))()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(23): const error = Error() + +> Input + + `␊ + 1 | const error = Error()␊ + ` + +> Output + + `␊ + 1 | const error = new Error()␊ + ` + +> Error 1/1 + + `␊ + > 1 | const error = Error()␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(24): throw Object.assign(Error(), {foo}) + +> Input + + `␊ + 1 | throw Object.assign(Error(), {foo})␊ + ` + +> Output + + `␊ + 1 | throw Object.assign(new Error(), {foo})␊ + ` + +> Error 1/1 + + `␊ + > 1 | throw Object.assign(Error(), {foo})␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(25): new Promise((resolve, reject) => { reject(Error('message')); }); + +> Input + + `␊ + 1 | new Promise((resolve, reject) => {␊ + 2 | reject(Error('message'));␊ + 3 | });␊ + ` + +> Output + + `␊ + 1 | new Promise((resolve, reject) => {␊ + 2 | reject(new Error('message'));␊ + 3 | });␊ + ` + +> Error 1/1 + + `␊ + 1 | new Promise((resolve, reject) => {␊ + > 2 | reject(Error('message'));␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ + 3 | });␊ ` diff --git a/test/snapshots/throw-new-error.mjs.snap b/test/snapshots/throw-new-error.mjs.snap index 740e4683ae..aa2b8ade04 100644 Binary files a/test/snapshots/throw-new-error.mjs.snap and b/test/snapshots/throw-new-error.mjs.snap differ diff --git a/test/throw-new-error.mjs b/test/throw-new-error.mjs index 52b6512066..e240b19e77 100644 --- a/test/throw-new-error.mjs +++ b/test/throw-new-error.mjs @@ -1,3 +1,4 @@ +import {outdent} from 'outdent'; import {getTester} from './utils/test.mjs'; const {test} = getTester(import.meta); @@ -52,5 +53,12 @@ test.snapshot({ 'throw getGlobalThis().Error()', 'throw utils.getGlobalThis().Error()', 'throw (( getGlobalThis().Error ))()', + 'const error = Error()', + 'throw Object.assign(Error(), {foo})', + outdent` + new Promise((resolve, reject) => { + reject(Error('message')); + }); + `, ], });