Skip to content

Commit 92d8a5a

Browse files
FL4TLiN3claude
andauthored
chore: add byte-level debug logging for startRun parse failure (#718)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0aa8d23 commit 92d8a5a

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

e2e/perstack-cli/providers.test.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,40 +33,44 @@ describe.concurrent("LLM Providers", () => {
3333
const result = withEventParsing(cmdResult)
3434
const seqResult = assertEventSequenceContains(result.events, ["startRun", "completeRun"])
3535
if (!seqResult.passed) {
36+
const lines = result.stdout.split("\n")
37+
const startRunLineIdx = lines.findIndex((l) => l.includes('"startRun"'))
3638
process.stderr.write(
3739
`[DEBUG ${provider}] exitCode=${result.exitCode} eventTypes=${JSON.stringify(result.events.map((e) => e.type))}\n`,
3840
)
39-
const startRunIdx = result.stdout.indexOf('"startRun"')
40-
process.stderr.write(`[DEBUG ${provider}] startRun at index=${startRunIdx}\n`)
41-
if (startRunIdx >= 0) {
42-
const lineStart = result.stdout.lastIndexOf("\n", startRunIdx)
43-
const lineEnd = result.stdout.indexOf("\n", startRunIdx)
44-
const startRunLine = result.stdout.slice(
45-
Math.max(0, lineStart),
46-
lineEnd > 0 ? Math.min(lineEnd + 200, result.stdout.length) : startRunIdx + 500,
41+
if (startRunLineIdx >= 0) {
42+
const line = lines[startRunLineIdx]
43+
const first50 = Array.from(line.slice(0, 50)).map((c) => c.charCodeAt(0))
44+
const last50 = Array.from(line.slice(-50)).map((c) => c.charCodeAt(0))
45+
process.stderr.write(
46+
`[DEBUG ${provider}] startRunLine idx=${startRunLineIdx} len=${line.length}\n`,
4747
)
48+
process.stderr.write(`[DEBUG ${provider}] first50codes=${JSON.stringify(first50)}\n`)
49+
process.stderr.write(`[DEBUG ${provider}] last50codes=${JSON.stringify(last50)}\n`)
4850
process.stderr.write(
49-
`[DEBUG ${provider}] startRun line (len=${startRunLine.length}): ${startRunLine.slice(0, 300)}\n`,
51+
`[DEBUG ${provider}] hasNull=${line.includes("\0")} hasCR=${line.includes("\r")}\n`,
5052
)
5153
try {
52-
const parsed = JSON.parse(startRunLine.trim())
53-
process.stderr.write(`[DEBUG ${provider}] startRun parsed OK, type=${parsed.type}\n`)
54+
JSON.parse(line)
55+
process.stderr.write(`[DEBUG ${provider}] parse OK\n`)
5456
} catch (e) {
55-
process.stderr.write(
56-
`[DEBUG ${provider}] startRun PARSE FAIL: ${(e as Error).message}\n`,
57-
)
58-
process.stderr.write(
59-
`[DEBUG ${provider}] startRun last200: ...${startRunLine.slice(-200)}\n`,
60-
)
57+
const msg = (e as Error).message
58+
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+
)
69+
}
6170
}
71+
} else {
72+
process.stderr.write(`[DEBUG ${provider}] startRun NOT FOUND in any line\n`)
6273
}
63-
const lines = result.stdout.split("\n")
64-
process.stderr.write(
65-
`[DEBUG ${provider}] totalLines=${lines.length} lineStarts=${lines
66-
.slice(0, 10)
67-
.map((l) => l.slice(0, 30))
68-
.join(" | ")}\n`,
69-
)
7074
}
7175
expect(result.exitCode).toBe(0)
7276
expect(seqResult.passed).toBe(true)

0 commit comments

Comments
 (0)