From 264bdebf18e52c19cd25fa8b3deb7862b816ed2a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:19:53 +0000 Subject: [PATCH 1/5] Initial plan From cfc8d132dd2d74ea9aeef28621d1bea60a68472d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:30:29 +0000 Subject: [PATCH 2/5] fix(eslint-factory): avoid useless catch in JSON.parse suggestion Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../require-json-parse-try-catch.test.ts | 22 +++++++++---------- .../src/rules/require-json-parse-try-catch.ts | 5 ++++- 2 files changed, 15 insertions(+), 12 deletions(-) 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..6c72d5b98f4 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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\n} }); } catch (e) {}`, }, ], }, @@ -245,7 +245,7 @@ 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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\n} }); } catch (e) {}`, }, ], }, 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..7876a241d89 100644 --- a/eslint-factory/src/rules/require-json-parse-try-catch.ts +++ b/eslint-factory/src/rules/require-json-parse-try-catch.ts @@ -158,7 +158,10 @@ 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, + `try {\n${indent} ${stmtText}\n${indent}} catch (err) {\n${indent} // TODO: handle parse failure for this code path.\n${indent} throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\n${indent}}` + ); }, }, ], From 62aeaab56a0e8798c961f2be1e5f440d471d395c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:39:46 +0000 Subject: [PATCH 3/5] refactor(eslint-factory): make JSON.parse suggestion catch meaningful Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../require-json-parse-try-catch.test.ts | 22 +++++++++---------- .../src/rules/require-json-parse-try-catch.ts | 18 +++++++++++---- 2 files changed, 25 insertions(+), 15 deletions(-) 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 6c72d5b98f4..6c6f96a055b 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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\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 // TODO: handle parse failure for this code path.\n throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\n} }); } catch (e) {}`, }, ], }, @@ -245,7 +245,7 @@ describe("require-json-parse-try-catch", () => { suggestions: [ { messageId: "useHelper", - 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(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(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 );\n} }); } catch (e) {}`, }, ], }, 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 7876a241d89..f5472a71831 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,19 @@ 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} );`, + `${indent}}`, + ].join("\n"); +} + export const requireJsonParseTryCatchRule = createRule({ name: "require-json-parse-try-catch", meta: { @@ -158,10 +171,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} // TODO: handle parse failure for this code path.\n${indent} throw new Error(\`Failed to parse JSON: \${err instanceof Error ? err.message : String(err)}\`);\n${indent}}` - ); + return fixer.replaceText(stmt, buildTryCatchSuggestion(stmtText, indent)); }, }, ], From 2ab8d9a14af17efad41ad778af290feb13e7dcc4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:07:14 +0000 Subject: [PATCH 4/5] chore: start PR finisher pass Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/mattpocock-skills-reviewer.lock.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mattpocock-skills-reviewer.lock.yml b/.github/workflows/mattpocock-skills-reviewer.lock.yml index 2280323fb07..2677ae9206f 100644 --- a/.github/workflows/mattpocock-skills-reviewer.lock.yml +++ b/.github/workflows/mattpocock-skills-reviewer.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"26e8a754482b7347113adc6d77b27f62e3dee49e84d972a2e35662fd319720b5","body_hash":"62ce0bd5c9851424f73f018934c48ae0ca6493b0bc7415fdc5564e808707829a","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.65"}} -# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.13","digest":"sha256:691a06b64961b5b35aac117eaace202fa721e91da19d1d2e22dcdd6663cd571b","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.13@sha256:691a06b64961b5b35aac117eaace202fa721e91da19d1d2e22dcdd6663cd571b"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.13","digest":"sha256:c57febf4aeeefbb4fd96f5b12c07f4279ca55edca6a700032debf9dd0787286e","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.13@sha256:c57febf4aeeefbb4fd96f5b12c07f4279ca55edca6a700032debf9dd0787286e"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.13","digest":"sha256:79dfd3a5d139bd1956ba6d7d1782b831a07175cf5afa29c45cb20bb0140f23c5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.13@sha256:79dfd3a5d139bd1956ba6d7d1782b831a07175cf5afa29c45cb20bb0140f23c5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.13","digest":"sha256:700b1b5a73098373b04fb684f291e95d9be0124ab559717b04f27acaf8b41bed","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.13@sha256:700b1b5a73098373b04fb684f291e95d9be0124ab559717b04f27acaf8b41bed"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.32","digest":"sha256:63e46b56dfd70895a701b6fc6dd0189e11e2d875f327f1781e81b31848735477","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.32@sha256:63e46b56dfd70895a701b6fc6dd0189e11e2d875f327f1781e81b31848735477"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.5.0","digest":"sha256:e25564dccc9110a70a77b9df560cbde11aa392fcb5f08b9abe5c4ebc6d146ea4","pinned_image":"ghcr.io/github/github-mcp-server:v1.5.0@sha256:e25564dccc9110a70a77b9df560cbde11aa392fcb5f08b9abe5c4ebc6d146ea4"}]} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.15"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.15"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.15"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.15"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.32","digest":"sha256:63e46b56dfd70895a701b6fc6dd0189e11e2d875f327f1781e81b31848735477","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.32@sha256:63e46b56dfd70895a701b6fc6dd0189e11e2d875f327f1781e81b31848735477"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.5.0","digest":"sha256:e25564dccc9110a70a77b9df560cbde11aa392fcb5f08b9abe5c4ebc6d146ea4","pinned_image":"ghcr.io/github/github-mcp-server:v1.5.0@sha256:e25564dccc9110a70a77b9df560cbde11aa392fcb5f08b9abe5c4ebc6d146ea4"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ From d41e2b41856ef42d9b298f2223916f3b369b9066 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:15:41 +0000 Subject: [PATCH 5/5] fix(eslint-factory): preserve JSON.parse error cause Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../require-json-parse-try-catch.test.ts | 37 +++++++++++++------ .../src/rules/require-json-parse-try-catch.ts | 1 + 2 files changed, 27 insertions(+), 11 deletions(-) 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 6c6f96a055b..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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 // 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 );\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 f5472a71831..200052cb0c0 100644 --- a/eslint-factory/src/rules/require-json-parse-try-catch.ts +++ b/eslint-factory/src/rules/require-json-parse-try-catch.ts @@ -65,6 +65,7 @@ function buildTryCatchSuggestion(stmtText: string, indent: string): string { `${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");