no-undef on AggregateError
See original GitHub issueTell us about your environment
I’m using github-actions to run tests on my code.
–env-info got:
Environment Info:
Node version: v14.15.4
npm version: v6.14.10
Local ESLint version: v7.19.0 (Currently used)
Global ESLint version: Not found
- Operating System: I’m using github actions, so it tests on all 3 of the following:
- ubuntu-latest
- macos-latest
- windows-latest
However ubuntu-latest failed first, so github-actions skipped the other checks.
What parser (default, @babel/eslint-parser
, @typescript-eslint/parser
, etc.) are you using?
@babel/eslint-parser
Please show your full configuration:
Configuration
You can see the file here: https://github.com/icecream17/tic-tac-toe-grow-for-website/blob/main/.github/workflows/main.yml
- uses: actions/setup-node@v2.1.4
with:
node-version: '14.15'
- name: Install babel eslint
run: npm install --save-dev eslint @babel/core @babel/eslint-parser @babel/eslint-plugin @babel/preset-env @babel/plugin-syntax-class-properties
What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.
// My code is 1446 lines long, so much of it isn't really important to this issue
// So here, you can see the basic structure and better understand where the error is happening.
//////////////////////////////////////
async function example() {
// Simulates chance of error happening sometime in the future............
// In the real code the error is inside an if statement too.
if (Math.random()) {
let promiseGroup = await Promise.allSettled([1, 2, 3])
throw new AggregateError(promiseGroup);
}
}
// Browser call
document.someElement.onclick = example();
- name: Check game.js
run: ./node_modules/.bin/eslint --format codeframe --color game.js
- name: Check tournament.js
run: ./node_modules/.bin/eslint --format codeframe --color tournament.js
Which corresponds to
./node_modules/.bin/eslint --format codeframe --color game.js
It failed at “game.js” so it didn’t get to do “tournament.js”.
What did you expect to happen? No errors when using AggregateError
What actually happened? Please copy-paste the actual, raw output from ESLint. no-undef: AggregateError is not defined
Better highlighting at: https://github.com/icecream17/tic-tac-toe-grow-for-website/runs/1888640229?check_suite_focus=true
Wow, raw output.
warning: Return values from promise executor functions cannot be read (no-promise-executor-return) at game.js:23:40:
21 | */
22 | async function pause(ms) {
> 23 | return await new Promise(resolve => setTimeout(resolve, ms, "Done!"));
| ^
24 | }
25 |
26 | /**
warning: Missing semicolon (@babel/semi) at game.js:46:25:
44 | if (this[i] !== arr[i])
45 | if (!Array.isArray(this[i]) || !Array.isArray(arr[i]))
> 46 | return false
| ^
47 | else if (!this[i].valuesEqual(arr[i]))
48 | return false;
49 | return true;
warning: Missing semicolon (@babel/semi) at game.js:50:2:
48 | return false;
49 | return true;
> 50 | }
| ^
51 |
52 | /**
53 | * Represents an explicit and somewhat anticipated error
warning: This line has a length of 127. Maximum allowed is 120 (max-len) at game.js:72:1:
70 | * I'll just say it's not under the Apache License.
71 | *
> 72 | * @param {...*} [args] - The args to the Error constructor. The only guaranteed argument is a string for the error message.
| ^
73 | */
74 | constructor (...args) {
75 | super(...args);
warning: Unnecessary { after 'if' condition (curly) at game.js:79:7:
77 | // Maintains proper stack trace for where our error was thrown (only available on V8)
78 | // You must be pretty sure, and have a really good reason to pass this if statement
> 79 | if (String(Error?.captureStackTrace).includes("native code")) {
| ^
80 | Error.captureStackTrace(this, CustomError);
81 | } else {
82 | this.stack = (new Error(...args)).stack;
warning: Unnecessary { after 'else' (curly) at game.js:81:9:
79 | if (String(Error?.captureStackTrace).includes("native code")) {
80 | Error.captureStackTrace(this, CustomError);
> 81 | } else {
| ^
82 | this.stack = (new Error(...args)).stack;
83 | }
84 | }
warning: Operator '=' must be spaced (space-infix-ops) at game.js:98:20:
96 | * Derived from https://stackoverflow.com/a/42755876 by Matt
97 | */
> 98 | rethrow (message=this.message, ...args) {
| ^
99 | if (message !== this.message) {
100 | let newError = new (this.constructor)(message, ...args);
101 | newError.originalError = this;
warning: Unexpected negated condition (no-negated-condition) at game.js:99:7:
97 | */
98 | rethrow (message=this.message, ...args) {
> 99 | if (message !== this.message) {
| ^
100 | let newError = new (this.constructor)(message, ...args);
101 | newError.originalError = this;
102 | newError.stack = `${newError.stack}\n${this.stack}`;
warning: Unnecessary parentheses around expression (no-extra-parens) at game.js:100:29:
98 | rethrow (message=this.message, ...args) {
99 | if (message !== this.message) {
> 100 | let newError = new (this.constructor)(message, ...args);
| ^
101 | newError.originalError = this;
102 | newError.stack = `${newError.stack}\n${this.stack}`;
103 | throw newError;
warning: Unnecessary parentheses around expression (no-extra-parens) at game.js:105:27:
103 | throw newError;
104 | } else {
> 105 | this.stack = new (this.constructor)(message, ...args);
| ^
106 | throw this;
107 | }
108 | }
warning: Expected an error object to be thrown (no-throw-literal) at game.js:106:10:
104 | } else {
105 | this.stack = new (this.constructor)(message, ...args);
> 106 | throw this;
| ^
107 | }
108 | }
109 | }
warning: This line has a length of 132. Maximum allowed is 120 (max-len) at game.js:124:1:
122 |
123 | class NothingDisabledError extends CustomError {
> 124 | constructor (noun = "Nothing", plural = `${noun}s`, message = `Cannot enable ${noun} since all ${plural} are already enabled.`) {
| ^
125 | super(message);
126 | }
127 | }
warning: This line has a length of 134. Maximum allowed is 120 (max-len) at game.js:130:1:
128 |
129 | class NothingEnabledError extends CustomError {
> 130 | constructor (noun = "Nothing", plural = `${noun}s`, message = `Cannot disable ${noun} since all ${plural} are already disabled.`) {
| ^
131 | super(message);
132 | }
133 | }
warning: 'NOT_DONE_YET' is assigned a value but never used (no-unused-vars) at game.js:220:7:
218 | EVIL_CHANGE: new EvilPlayerError("How did you do that"),
219 | };
> 220 | const NOT_DONE_YET = "This feature is not finished yet. So it doesn't work";
| ^
221 |
222 | class Position {
223 | constructor (x, y) {
warning: Expected indentation of 6 spaces but found 9 (indent) at game.js:394:1:
392 | // Converted from an "if, else if, else" statement.
393 | switch (result[0]) {
> 394 | case "win":
| ^
395 | {
396 | notice("WINNNN", result);
397 | for (let cell of result[1].flat().concat(this.board[lastY][lastX]))
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:395:1:
393 | switch (result[0]) {
394 | case "win":
> 395 | {
| ^
396 | notice("WINNNN", result);
397 | for (let cell of result[1].flat().concat(this.board[lastY][lastX]))
398 | cell.win = true;
warning: Expected indentation of 12 spaces but found 15 (indent) at game.js:396:1:
394 | case "win":
395 | {
> 396 | notice("WINNNN", result);
| ^
397 | for (let cell of result[1].flat().concat(this.board[lastY][lastX]))
398 | cell.win = true;
399 |
warning: Expected indentation of 12 spaces but found 15 (indent) at game.js:397:1:
395 | {
396 | notice("WINNNN", result);
> 397 | for (let cell of result[1].flat().concat(this.board[lastY][lastX]))
| ^
398 | cell.win = true;
399 |
400 | let winArray = [this.toMove, PLAYER_NAMES[this.toMove], players[this.toMove].player];
warning: Expected indentation of 15 spaces but found 18 (indent) at game.js:398:1:
396 | notice("WINNNN", result);
397 | for (let cell of result[1].flat().concat(this.board[lastY][lastX]))
> 398 | cell.win = true;
| ^
399 |
400 | let winArray = [this.toMove, PLAYER_NAMES[this.toMove], players[this.toMove].player];
401 | if (this.winners.every(array => !array.valuesEqual(winArray)))
warning: Expected indentation of 12 spaces but found 15 (indent) at game.js:400:1:
398 | cell.win = true;
399 |
> 400 | let winArray = [this.toMove, PLAYER_NAMES[this.toMove], players[this.toMove].player];
| ^
401 | if (this.winners.every(array => !array.valuesEqual(winArray)))
402 | this.winners.push(winArray);
403 | }
warning: Expected indentation of 12 spaces but found 15 (indent) at game.js:401:1:
399 |
400 | let winArray = [this.toMove, PLAYER_NAMES[this.toMove], players[this.toMove].player];
> 401 | if (this.winners.every(array => !array.valuesEqual(winArray)))
| ^
402 | this.winners.push(winArray);
403 | }
404 | break;
warning: Expected indentation of 15 spaces but found 18 (indent) at game.js:402:1:
400 | let winArray = [this.toMove, PLAYER_NAMES[this.toMove], players[this.toMove].player];
401 | if (this.winners.every(array => !array.valuesEqual(winArray)))
> 402 | this.winners.push(winArray);
| ^
403 | }
404 | break;
405 | case "draw":
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:403:1:
401 | if (this.winners.every(array => !array.valuesEqual(winArray)))
402 | this.winners.push(winArray);
> 403 | }
| ^
404 | break;
405 | case "draw":
406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:404:1:
402 | this.winners.push(winArray);
403 | }
> 404 | break;
| ^
405 | case "draw":
406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
407 | break;
warning: Expected indentation of 6 spaces but found 9 (indent) at game.js:405:1:
403 | }
404 | break;
> 405 | case "draw":
| ^
406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
407 | break;
408 | default:
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:406:1:
404 | break;
405 | case "draw":
> 406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
| ^
407 | break;
408 | default:
409 | ERRORS.INVALID_MOVE_FINISH.rethrow();
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:407:1:
405 | case "draw":
406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
> 407 | break;
| ^
408 | default:
409 | ERRORS.INVALID_MOVE_FINISH.rethrow();
410 | }
warning: Expected indentation of 6 spaces but found 9 (indent) at game.js:408:1:
406 | notice(`*gasp*! Draw!\n${result[1]}`, result);
407 | break;
> 408 | default:
| ^
409 | ERRORS.INVALID_MOVE_FINISH.rethrow();
410 | }
411 | }
warning: Expected indentation of 9 spaces but found 12 (indent) at game.js:409:1:
407 | break;
408 | default:
> 409 | ERRORS.INVALID_MOVE_FINISH.rethrow();
| ^
410 | }
411 | }
412 |
warning: Missing semicolon (@babel/semi) at game.js:454:8:
452 |
453 | return diag;
> 454 | }
| ^
455 |
456 | for (let i = 0; i < 4; i++) {
457 | const orthogonalStep = [
warning: Missing semicolon (@babel/semi) at game.js:554:8:
552 |
553 | return newWins;
> 554 | }
| ^
555 |
556 | wins.push(...checkmarks(diagonal[0], diagonal[3], new Step(1, -1), new Step(-1, 1)));
557 | wins.push(...checkmarks(diagonal[1], diagonal[2], new Step(1, 1), new Step(-1, -1)));
warning: Missing semicolon (@babel/semi) at game.js:600:26:
598 | for (let x = 0; x < this.board.width; x++) {
599 | let char = this.board[y][x].value;
> 600 | ascii += '%c'
| ^
601 | if (char === '') {
602 | ascii += ' ';
603 | css.push('background-color:gray');
warning: Unexpected string concatenation (prefer-template) at game.js:610:19:
608 | ascii += char;
609 | css.push(
> 610 | "color:"
| ^
611 | + ['red', 'blue', 'green', 'orange', 'purple'][PLAYER_CHARS.indexOf(char)]
612 | + (this.board[y][x].win ? ';background-color:#CFC' : '')
613 | );
warning: Missing semicolon (@babel/semi) at game.js:625:8:
623 | 'background-color:gray;color:gray',
624 | 'color:white'
> 625 | )
| ^
626 |
627 | if (verbose) console.debug(ascii, ...css);
628 | else console.log(ascii, ...css);
warning: '=' should be placed at the beginning of the line (operator-linebreak) at game.js:750:41:
748 |
749 | updateVisualStats() {
> 750 | ELEMENTS.statsParagraph.innerText =
| ^
751 | `Width: ${this.board.width}
752 | Height: ${this.board.height}
753 | Turns: ${this.turn}`;
warning: 'args' is defined but never used (no-unused-vars) at game.js:823:20:
821 | }
822 |
> 823 | function notice(...args) {
| ^
824 | // TODO: do something
825 | }
826 |
warning: Missing semicolon (@babel/semi) at game.js:921:2:
919 | currentGame.updateVisual();
920 | currentGame.updateVisualStats();
> 921 | }
| ^
922 |
923 | // Assumes that the enable and disable buttons are disabled / enabled when appropriate.
924 | // For example, the enable button should not be enabled if the element is already enabled.
warning: Unnecessary parentheses around expression (no-extra-parens) at game.js:1053:32:
1051 | bot_mechanics.random_move.apply(this);
1052 | else {
> 1053 | let indexOfLastMove = (
| ^
1054 | lastMove.gameState
1055 | .originalMoves
1056 | .findIndex(
warning: Missing semicolon (@babel/semi) at game.js:1071:39:
1069 | avoider() {
1070 | let moves = this.getMoves();
> 1071 | let best_moves = [-Infinity, []]
| ^
1072 | for (let move of moves) {
1073 | let score = 0;
1074 | for (let historicalMove of this.moveHistory)
warning: Unnecessary parentheses around expression (no-extra-parens) at game.js:1110:50:
1108 | } else positionOnDiagonal = new Position(0, 0);
1109 |
> 1110 | let moves = this.getMoves().filter(move => (
| ^
1111 | (positionOnDiagonal.x + positionOnDiagonal.y + move.x + move.y) % 2 === 0
1112 | ));
1113 | if (moves.length === 0)
warning: A function with a name starting with an uppercase letter should only be used as a constructor (@babel/new-cap) at game.js:1220:33:
1218 |
1219 | let localIndex = Array.prototype.indexOf.call(option.parentElement.children, option);
> 1220 | if (localIndex === -1) throw ReferenceError("No player is selected!??");
| ^
1221 |
1222 | players[playerIndex] = new PlayerReference(type, localIndex);
1223 | currentGame.playBots();
warning: Operator '=' must be spaced (space-infix-ops) at game.js:1239:45:
1237 |
1238 | // this = <input>
> 1239 | async function enablePerson(fromEnablePeople=false) {
| ^
1240 | // MAX_PLAYERS_REACHED and EVERYONEs_ENABLED both fit...
1241 | if (activePeople === 4) ERRORS.EVERYONEs_ENABLED.rethrow();
1242 | activePeople++;
warning: Operator '=' must be spaced (space-infix-ops) at game.js:1260:47:
1258 |
1259 | // Bug, probably feature: Player not changed when disabled
> 1260 | async function disablePerson(fromDisablePeople=false) {
| ^
1261 | if (activePeople === 0) ERRORS.NO_ONEs_ENABLED.rethrow();
1262 | activePeople--;
1263 |
error: 'AggregateError' is not defined (no-undef) at game.js:1294:52:
1292 | let promiseGroup = await Promise.allSettled(clickPromises);
1293 | for (let promise of promiseGroup)
> 1294 | if (promise.status === 'rejected') throw new AggregateError(promiseGroup);
| ^
1295 |
1296 | if (counter !== num)
1297 | console.warn(`Failed to enable the correct amount: ${counter} !== ${num}`);
error: 'AggregateError' is not defined (no-undef) at game.js:1317:52:
1315 | let promiseGroup = await Promise.allSettled(clickPromises);
1316 | for (let promise of promiseGroup)
> 1317 | if (promise.status === 'rejected') throw new AggregateError(promiseGroup);
| ^
1318 |
1319 | activePeople = counter;
1320 | if (counter !== num)
warning: Possible race condition: `activePeople` might be reassigned based on an outdated value of `activePeople` (require-atomic-updates) at game.js:1319:4:
1317 | if (promise.status === 'rejected') throw new AggregateError(promiseGroup);
1318 |
> 1319 | activePeople = counter;
| ^
1320 | if (counter !== num)
1321 | console.warn(`Failed to disable the correct amount: ${counter} !== ${num}`);
1322 |
warning: Operator '=' must be spaced (space-infix-ops) at game.js:1327:46:
1325 |
1326 | // this = <select disabled>
> 1327 | async function enablePlayer(fromEnablePlayers=false) {
| ^
1328 | if (activePlayers === 4) ERRORS.MAX_PLAYERS_REACHED.rethrow();
1329 |
1330 | let playerIndex = this.parentElement.id[8] - 1;
warning: 'fromDisablePlayers' is assigned a value but never used (no-unused-vars) at game.js:1358:30:
1356 | // Min players: !1 (apparently it's 0)
1357 | // this = <input (not:disabled)>
> 1358 | async function disablePlayer(fromDisablePlayers=false) {
| ^
1359 | if (activePlayers === 0) ERRORS.NO_ONEs_ENABLED.rethrow();
1360 |
1361 | let option = this.selectedOptions[0];
warning: Operator '=' must be spaced (space-infix-ops) at game.js:1358:48:
1356 | // Min players: !1 (apparently it's 0)
1357 | // this = <input (not:disabled)>
> 1358 | async function disablePlayer(fromDisablePlayers=false) {
| ^
1359 | if (activePlayers === 0) ERRORS.NO_ONEs_ENABLED.rethrow();
1360 |
1361 | let option = this.selectedOptions[0];
warning: Missing semicolon (@babel/semi) at game.js:1373:88:
1371 | ELEMENTS.playerSelects[playerIndexPlusOne].dispatchEvent(new Event("change"));
1372 |
> 1373 | return await disablePlayer.call(ELEMENTS.playerSelects[playerIndexPlusOne], true)
| ^
1374 | } else {
1375 | this.disabled = true;
1376 | this.parentElement.nextElementSibling.disabled = false;
warning: 'activeBots' is assigned a value but never used (no-unused-vars) at game.js:1383:50:
1381 |
1382 | // <optgroup> label
> 1383 | if (option.parentElement.label === "Bots") activeBots--;
| ^
1384 | else activePeople--;
1385 |
1386 | if (currentGame.toMove === playerIndexPlusOne - 1) {
error: 'AggregateError' is not defined (no-undef) at game.js:1411:52:
1409 | let promiseGroup = await Promise.allSettled(clickPromises);
1410 | for (let promise of promiseGroup)
> 1411 | if (promise.status === 'rejected') throw new AggregateError(promiseGroup);
| ^
1412 |
1413 | if (counter !== num)
1414 | console.warn(`Failed to enable the correct amount: ${counter} !== ${num}`);
error: 'AggregateError' is not defined (no-undef) at game.js:1433:52:
1431 | let promiseGroup = await Promise.allSettled(clickPromises);
1432 | for (let promise of promiseGroup)
> 1433 | if (promise.status === 'rejected') throw new AggregateError(promiseGroup);
| ^
1434 |
1435 | if (counter !== num)
1436 | console.warn(`Failed to disable the correct amount: ${counter} !== ${num}`);
4 errors and 49 warnings found.
37 warnings potentially fixable with the `--fix` option.
Error: Process completed with exit code 1.
Steps to reproduce this issue:
- Use AggregateError in your code
- Watch as your tests fail because AggregateError is not defined
Are you willing to submit a pull request to fix this bug? No
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (5 by maintainers)
Top GitHub Comments
Hi @icecream17, thanks for the issue!
I can see you fixed the issue for now by adding
"AggregateError"
toglobals
👍It seems that we missed adding this to built-in environments. By the finished proposals list, it looks like this should be in the
es2021
environment (the expected publication year for https://github.com/tc39/proposal-promise-any is 2021).Those two should be already there.