Skip to content

Commit 7d179dc

Browse files
FL4TLiN3claude
andauthored
chore: scan for non-ASCII chars and binary search parse failure region (#719)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 92d8a5a commit 7d179dc

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

e2e/perstack-cli/providers.test.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,45 @@ describe.concurrent("LLM Providers", () => {
5050
process.stderr.write(
5151
`[DEBUG ${provider}] hasNull=${line.includes("\0")} hasCR=${line.includes("\r")}\n`,
5252
)
53+
const badChars: { i: number; code: number }[] = []
54+
for (let i = 0; i < line.length; i++) {
55+
const code = line.charCodeAt(i)
56+
if (code < 32 || code > 126) {
57+
badChars.push({ i, code })
58+
}
59+
}
60+
if (badChars.length > 0) {
61+
process.stderr.write(
62+
`[DEBUG ${provider}] nonAscii=${JSON.stringify(badChars.slice(0, 20))}\n`,
63+
)
64+
} else {
65+
process.stderr.write(`[DEBUG ${provider}] allPrintableAscii=true\n`)
66+
}
5367
try {
5468
JSON.parse(line)
5569
process.stderr.write(`[DEBUG ${provider}] parse OK\n`)
5670
} catch (e) {
5771
const msg = (e as Error).message
5872
process.stderr.write(`[DEBUG ${provider}] parse FAIL: ${msg}\n`)
59-
const posMatch = msg.match(/position (\d+)/)
60-
if (posMatch) {
61-
const pos = Number.parseInt(posMatch[1])
62-
const around = Array.from(line.slice(Math.max(0, pos - 5), pos + 5)).map((c) =>
63-
c.charCodeAt(0),
64-
)
65-
process.stderr.write(`[DEBUG ${provider}] chars@${pos}: ${JSON.stringify(around)}\n`)
66-
process.stderr.write(
67-
`[DEBUG ${provider}] text@${pos}: ${JSON.stringify(line.slice(Math.max(0, pos - 20), pos + 20))}\n`,
68-
)
73+
let lo = 0
74+
let hi = line.length
75+
while (hi - lo > 100) {
76+
const mid = Math.floor((lo + hi) / 2)
77+
try {
78+
JSON.parse(line.slice(0, mid) + "}")
79+
lo = mid
80+
} catch {
81+
hi = mid
82+
}
6983
}
84+
process.stderr.write(`[DEBUG ${provider}] failRegion=[${lo},${hi}]\n`)
85+
const regionCodes = Array.from(line.slice(lo, Math.min(hi, lo + 100))).map((c) =>
86+
c.charCodeAt(0),
87+
)
88+
process.stderr.write(`[DEBUG ${provider}] regionCodes=${JSON.stringify(regionCodes)}\n`)
89+
process.stderr.write(
90+
`[DEBUG ${provider}] regionText=${JSON.stringify(line.slice(lo, Math.min(hi, lo + 100)))}\n`,
91+
)
7092
}
7193
} else {
7294
process.stderr.write(`[DEBUG ${provider}] startRun NOT FOUND in any line\n`)

0 commit comments

Comments
 (0)