fix(core): serialize Trace appends; tolerate malformed middle lines on read (#234)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9745773cb9
commit
4a899a265f
9 files changed
+344
-33
No files matched your search
@@ -2,9 +2,10 @@
|
||||
* Trace service.
|
||||
*
|
||||
* History messages: all of the Session's index files concatenated in order
|
||||
* (readTraceTolerant, tolerating a truncated last line), containing only the
|
||||
* complete messages and events that were actually written to Trace (naturally
|
||||
* excluding partial_*); in-flight increments are continued by SSE.
|
||||
* (readTraceTolerant, tolerating a truncated last line and skipping malformed
|
||||
* middle lines), containing only the complete messages and events that were
|
||||
* actually written to Trace (naturally excluding partial_*); in-flight
|
||||
* increments are continued by SSE.
|
||||
* Performance analysis is derived from a single Trace file: nearest-neighbor
|
||||
* pairing of request_begin/end, tool call duration pairing, reconnect / compaction
|
||||
* counts, and Token trend.
|
||||
@@ -1206,7 +1207,9 @@ export class TraceService {
|
||||
const invalid = (message: string) => new HttpError(400, "invalid_trace", message);
|
||||
let records: OmniMessage[];
|
||||
try {
|
||||
records = parseTraceLines(content);
|
||||
// Strict parse: import is the gate for user-supplied files, so a malformed middle
|
||||
// line is reported as 400 rather than silently dropped (read paths skip it instead).
|
||||
records = parseTraceLines(content, { onMalformed: "throw" });
|
||||
} catch {
|
||||
throw invalid("The file is not valid Trace JSONL.");
|
||||
}
|
||||
|
||||
@@ -189,7 +189,10 @@ describe("trace-import-export", () => {
|
||||
|
||||
it("import: malformed middle line → 400 invalid_trace", async () => {
|
||||
const lines = toContent(sampleTrace(SID)).split("\n");
|
||||
lines[1] = "{not json"; // corrupt a middle line (non-final: parseTraceLines throws loudly)
|
||||
// Corrupt a middle (non-final) line. Read paths skip malformed middle lines (#215
|
||||
// recovery), but import validates strictly (onMalformed: "throw") — damage in an
|
||||
// uploaded file is reported, not silently dropped.
|
||||
lines[1] = "{not json";
|
||||
const res = await owner.post(`${base()}/import`, { dataBase64: b64(lines.join("\n")) });
|
||||
expect(res.status).toBe(400);
|
||||
expect(await errorCode(res)).toBe("invalid_trace");
|
||||
|
||||
Reference in new issue
Block a user