From 5d04f01c82327aa8c0a292d6c1f5b9cf1d9e8d60 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 21 Feb 2023 16:34:42 +0800 Subject: [PATCH] Make `tryCombinations` throws `AggregateError(like)` error (#14388) --- src/language-js/parse/acorn.js | 7 ++++--- src/language-js/parse/babel.js | 14 ++++++++------ src/language-js/parse/espree.js | 7 ++++--- src/language-js/parse/meriyah.js | 6 ++++-- src/language-js/parse/typescript.js | 23 ++++++++++++++--------- src/utils/try-combinations.js | 15 ++++++++------- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/language-js/parse/acorn.js b/src/language-js/parse/acorn.js index 7b23d38c1..d7746b8af 100644 --- a/src/language-js/parse/acorn.js +++ b/src/language-js/parse/acorn.js @@ -72,9 +72,10 @@ function parse(text, options = {}) { (sourceType) => () => parseWithOptions(text, sourceType) ); - const { result: ast, error } = tryCombinations(combinations); - - if (!ast) { + let ast; + try { + ast = tryCombinations(combinations); + } catch ({ errors: [error] }) { throw createParseError(error); } diff --git a/src/language-js/parse/babel.js b/src/language-js/parse/babel.js index 3862af1f3..816666304 100644 --- a/src/language-js/parse/babel.js +++ b/src/language-js/parse/babel.js @@ -145,13 +145,15 @@ function createParse({ isExpression = false, optionsCombinations }) { /** @type {Parse} */ const parseFunction = isExpression ? parseExpression : babelParse; - let { result: ast, error } = tryCombinations( - combinations.map( - (options) => () => parseWithOptions(parseFunction, text, options) - ) - ); - if (!ast) { + let ast; + try { + ast = tryCombinations( + combinations.map( + (options) => () => parseWithOptions(parseFunction, text, options) + ) + ); + } catch ({ errors: [error] }) { throw createBabelParseError(error); } diff --git a/src/language-js/parse/espree.js b/src/language-js/parse/espree.js index 3d18b1538..09eb7e837 100644 --- a/src/language-js/parse/espree.js +++ b/src/language-js/parse/espree.js @@ -45,9 +45,10 @@ function parse(text, options = {}) { espreeParse(text, { ...parseOptions, sourceType }) ); - const { result: ast, error } = tryCombinations(combinations); - - if (!ast) { + let ast; + try { + ast = tryCombinations(combinations); + } catch ({ errors: [error] }) { throw createParseError(error); } diff --git a/src/language-js/parse/meriyah.js b/src/language-js/parse/meriyah.js index 4b5b80332..6d2ff5eb4 100644 --- a/src/language-js/parse/meriyah.js +++ b/src/language-js/parse/meriyah.js @@ -91,9 +91,11 @@ function parse(text, options = {}) { const combinations = (sourceType ? [sourceType] : ["module", "script"]).map( (sourceType) => () => parseWithOptions(text, sourceType) ); - const { result: ast, error } = tryCombinations(combinations); - if (!ast) { + let ast; + try { + ast = tryCombinations(combinations); + } catch ({ errors: [error] }) { throw createParseError(error); } diff --git a/src/language-js/parse/typescript.js b/src/language-js/parse/typescript.js index a545aa91b..60863c49e 100644 --- a/src/language-js/parse/typescript.js +++ b/src/language-js/parse/typescript.js @@ -41,15 +41,20 @@ function parse(text, options = {}) { const textToParse = replaceHashbang(text); const jsx = isProbablyJsx(text); - const { result, error } = tryCombinations([ - // Try passing with our best guess first. - () => parseWithNodeMaps(textToParse, { ...parseOptions, jsx }), - // But if we get it wrong, try the opposite. - () => parseWithNodeMaps(textToParse, { ...parseOptions, jsx: !jsx }), - ]); - - if (!result) { - // Suppose our guess is correct, throw the first error + let result; + try { + result = tryCombinations([ + // Try passing with our best guess first. + () => parseWithNodeMaps(textToParse, { ...parseOptions, jsx }), + // But if we get it wrong, try the opposite. + () => parseWithNodeMaps(textToParse, { ...parseOptions, jsx: !jsx }), + ]); + } catch ({ + errors: [ + // Suppose our guess is correct, throw the first error + error, + ], + }) { throw createParseError(error); } diff --git a/src/utils/try-combinations.js b/src/utils/try-combinations.js index 4f628f27f..7ef0871b6 100644 --- a/src/utils/try-combinations.js +++ b/src/utils/try-combinations.js @@ -1,15 +1,16 @@ function tryCombinations(combinations) { - let firstError; - for (const [index, fn] of combinations.entries()) { + const errors = []; + for (const fn of combinations) { try { - return { result: fn() }; + return fn(); } catch (error) { - if (index === 0) { - firstError = error; - } + errors.push(error); } } - return { error: firstError }; + + // TODO: Use `AggregateError` when we drop Node.js v14 + // throw new AggregateError(errors, "All combinations failed"); + throw Object.assign(new Error("All combinations failed"), { errors }); } export default tryCombinations;