diff --git a/eslint-factory/src/rules/require-json-parse-try-catch.test.ts b/eslint-factory/src/rules/require-json-parse-try-catch.test.ts index af9713efc86..c58db7c8878 100644 --- a/eslint-factory/src/rules/require-json-parse-try-catch.test.ts +++ b/eslint-factory/src/rules/require-json-parse-try-catch.test.ts @@ -44,7 +44,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n const data = JSON.parse(rawInput);\n} catch (err) {\n throw err;\n}`, + output: `try {\n const data = JSON.parse(rawInput);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -59,7 +59,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n JSON.parse(response.body);\n} catch (err) {\n throw err;\n}`, + output: `try {\n JSON.parse(response.body);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -82,7 +82,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n const data = JSON.parse(rawInput);\n} catch (err) {\n throw err;\n}`, + output: `try {\n const data = JSON.parse(rawInput);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -104,7 +104,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n const result = JSON.parse(text);\n} catch (err) {\n throw err;\n}`, + output: `try {\n const result = JSON.parse(text);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -127,7 +127,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n const data = JSON["parse"](rawInput);\n} catch (err) {\n throw err;\n}`, + output: `try {\n const data = JSON["parse"](rawInput);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -142,7 +142,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try {\n JSON["parse"](response.body);\n} catch (err) {\n throw err;\n}`, + output: `try {\n JSON["parse"](response.body);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n}`, }, ], }, @@ -181,7 +181,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try { emitter.on("data", chunk => { try {\n JSON.parse(chunk);\n} catch (err) {\n throw err;\n} }); } catch (e) {}`, + output: `try { emitter.on("data", chunk => { try {\n JSON.parse(chunk);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n} }); } catch (e) {}`, }, ], }, @@ -197,7 +197,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try { promise.then(data => { try {\n const x = JSON.parse(data);\n} catch (err) {\n throw err;\n} }); } catch (e) {}`, + output: `try { promise.then(data => { try {\n const x = JSON.parse(data);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n} }); } catch (e) {}`, }, ], }, @@ -213,7 +213,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try { setTimeout(() => { try {\n JSON.parse(raw);\n} catch (err) {\n throw err;\n} }, 100); } catch (e) {}`, + output: `try { setTimeout(() => { try {\n JSON.parse(raw);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n} }, 100); } catch (e) {}`, }, ], }, @@ -229,7 +229,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try { new Promise(resolve => { try {\n JSON.parse(data);\n} catch (err) {\n throw err;\n} }); } catch (e) {}`, + output: `try { new Promise(resolve => { try {\n JSON.parse(data);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n} }); } catch (e) {}`, }, ], }, @@ -245,7 +245,22 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - output: `try { process.nextTick(() => { try {\n JSON.parse(payload);\n} catch (err) {\n throw err;\n} }); } catch (e) {}`, + output: `try { process.nextTick(() => { try {\n JSON.parse(payload);\n} catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n} }); } catch (e) {}`, + }, + ], + }, + ], + }, + { + code: `if (cond) {\n JSON.parse(raw);\n}`, + errors: [ + { + messageId: "requireTryCatch", + data: { arg: "raw" }, + suggestions: [ + { + messageId: "useHelper", + output: `if (cond) {\n try {\n JSON.parse(raw);\n } catch (err) {\n // TODO: handle parse failure for this code path.\n throw new Error(\n "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),\n { cause: err },\n );\n }\n}`, }, ], }, diff --git a/eslint-factory/src/rules/require-json-parse-try-catch.ts b/eslint-factory/src/rules/require-json-parse-try-catch.ts index 0b46d67a075..200052cb0c0 100644 --- a/eslint-factory/src/rules/require-json-parse-try-catch.ts +++ b/eslint-factory/src/rules/require-json-parse-try-catch.ts @@ -57,6 +57,20 @@ function isDeferredCallback(funcNode: TSESTree.Node): boolean { return false; } +function buildTryCatchSuggestion(stmtText: string, indent: string): string { + return [ + "try {", + `${indent} ${stmtText}`, + `${indent}} catch (err) {`, + `${indent} // TODO: handle parse failure for this code path.`, + `${indent} throw new Error(`, + `${indent} "Failed to parse JSON: " + (err instanceof Error ? err.message : String(err)),`, + `${indent} { cause: err },`, + `${indent} );`, + `${indent}}`, + ].join("\n"); +} + export const requireJsonParseTryCatchRule = createRule({ name: "require-json-parse-try-catch", meta: { @@ -158,7 +172,7 @@ export const requireJsonParseTryCatchRule = createRule({ const startLine = stmt.loc?.start.line; const stmtLine = startLine !== undefined ? (sourceCode.lines[startLine - 1] ?? "") : ""; const indent = stmtLine.match(/^(\s*)/)?.[1] ?? ""; - return fixer.replaceText(stmt, `try {\n${indent} ${stmtText}\n${indent}} catch (err) {\n${indent} throw err;\n${indent}}`); + return fixer.replaceText(stmt, buildTryCatchSuggestion(stmtText, indent)); }, }, ],