Skip to content

Commit

Permalink
throw-new-error: Check all call expressions instead of just argumen…
Browse files Browse the repository at this point in the history
…t of `ThrowStatement` (#2332)
  • Loading branch information
fisker committed May 7, 2024
1 parent f3771b1 commit 1626852
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 37 deletions.
10 changes: 5 additions & 5 deletions 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).

Expand All @@ -12,27 +12,27 @@ 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
throw TypeError('unicorn');
```

```js
throw lib.TypeError();
throw lib.TypeError('unicorn');
```

## Pass

```js
throw new Error();
const error = new Error('unicorn');
```

```js
throw new TypeError('unicorn');
```

```js
throw new lib.TypeError();
throw new lib.TypeError('unicorn');
```
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -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. || 🔧 | |

<!-- end auto-generated rules list -->

Expand Down
11 changes: 2 additions & 9 deletions rules/throw-new-error.js
Expand Up @@ -3,21 +3,14 @@ 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$/;

/** @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))
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions test/error-message.mjs
Expand Up @@ -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})',
],
});

Expand Down
15 changes: 15 additions & 0 deletions test/snapshots/error-message.mjs.md
Expand Up @@ -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
Expand Down
Binary file modified test/snapshots/error-message.mjs.snap
Binary file not shown.
113 changes: 91 additions & 22 deletions test/snapshots/throw-new-error.mjs.md
Expand Up @@ -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)()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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')
Expand All @@ -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')
Expand All @@ -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')
Expand All @@ -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')
Expand All @@ -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')
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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() ))
Expand All @@ -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 ))()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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 ))()
Expand All @@ -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 | });␊
`
Binary file modified test/snapshots/throw-new-error.mjs.snap
Binary file not shown.
8 changes: 8 additions & 0 deletions test/throw-new-error.mjs
@@ -1,3 +1,4 @@
import {outdent} from 'outdent';
import {getTester} from './utils/test.mjs';

const {test} = getTester(import.meta);
Expand Down Expand Up @@ -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'));
});
`,
],
});

0 comments on commit 1626852

Please sign in to comment.