mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
fix(snapshot): locate entry diagnostics by collection and index
Each snapshot entry is validated alone, so its schema issue path started at the entry. Prefix it with entries or workflow_entries and the entry index so the reason names the entry to repair, and match the header case's issue count without freezing the whole sentence. Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
612b330b3b
commit
4ad1eb5beb
3 files changed
+30
-12
No files matched your search
@@ -90,7 +90,23 @@ export const readAnalysisSnapshot = async (
|
||||
}
|
||||
};
|
||||
|
||||
/** Locate an entry's schema issues within its snapshot collection. */
|
||||
const locateEntryFailure = (
|
||||
cause: unknown,
|
||||
collection: string,
|
||||
index: number,
|
||||
): unknown =>
|
||||
cause instanceof z.ZodError
|
||||
? new z.ZodError(
|
||||
cause.issues.map((issue) => ({
|
||||
...issue,
|
||||
path: [collection, index, ...issue.path],
|
||||
})),
|
||||
)
|
||||
: cause;
|
||||
|
||||
const snapshotEntryReader = (kind: "provider" | "workflow") => {
|
||||
const collection = kind === "provider" ? "entries" : "workflow_entries";
|
||||
let seen = false;
|
||||
let entries: PreparedSnapshotEntry[] = [];
|
||||
let failure: { readonly cause: unknown } | undefined;
|
||||
@@ -102,8 +118,12 @@ const snapshotEntryReader = (kind: "provider" | "workflow") => {
|
||||
failure = undefined;
|
||||
},
|
||||
accept: (value) => {
|
||||
if (failure === undefined)
|
||||
if (failure !== undefined) return;
|
||||
try {
|
||||
entries.push(prepareSnapshotEntry(value, kind));
|
||||
} catch (cause: unknown) {
|
||||
throw locateEntryFailure(cause, collection, entries.length);
|
||||
}
|
||||
},
|
||||
reject: (cause) => {
|
||||
failure ??= { cause };
|
||||
@@ -113,9 +133,7 @@ const snapshotEntryReader = (kind: "provider" | "workflow") => {
|
||||
reader,
|
||||
finish: (): PreparedSnapshotEntry[] => {
|
||||
if (!seen)
|
||||
throw new TypeError(
|
||||
`Analysis snapshot ${kind === "provider" ? "entries" : "workflow_entries"} is missing`,
|
||||
);
|
||||
throw new TypeError(`Analysis snapshot ${collection} is missing`);
|
||||
if (failure !== undefined) throw failure.cause;
|
||||
return entries;
|
||||
},
|
||||
|
||||
@@ -24,8 +24,8 @@ cliTest(
|
||||
const call = await cli.sharedMcpCall!();
|
||||
for (const [document, field] of [
|
||||
[{ entries: [], workflow_entries: [] }, "target"],
|
||||
[{ entries: [{}], workflow_entries: [] }, "query_id"],
|
||||
[{ entries: [], workflow_entries: [{}] }, "query_id"],
|
||||
[{ entries: [{}], workflow_entries: [] }, "entries.0.query_id"],
|
||||
[{ entries: [], workflow_entries: [{}] }, "workflow_entries.0.query_id"],
|
||||
] as const) {
|
||||
const encoded = JSON.stringify(document);
|
||||
await writeFile(snapshot, encoded);
|
||||
@@ -60,8 +60,8 @@ cliTest(
|
||||
expect(error).not.toHaveProperty("cause");
|
||||
expect(error).not.toHaveProperty("stack");
|
||||
if (field === "target")
|
||||
expect(error.details?.reason).toBe(
|
||||
"Analysis snapshot validation failed at target: Invalid input: expected object, received undefined (2 more issues)",
|
||||
expect(error.details?.reason).toMatch(
|
||||
/ at target: .+ \(2 more issues\)$/,
|
||||
);
|
||||
}
|
||||
// MCP adds open-session facts; the snapshot reason must match exactly.
|
||||
|
||||
@@ -33,12 +33,12 @@ describe.each([
|
||||
{
|
||||
label: "provider entry",
|
||||
document: { entries: [{}], workflow_entries: [] },
|
||||
field: "query_id",
|
||||
field: "entries.0.query_id",
|
||||
},
|
||||
{
|
||||
label: "workflow entry",
|
||||
document: { entries: [], workflow_entries: [{}] },
|
||||
field: "query_id",
|
||||
field: "workflow_entries.0.query_id",
|
||||
},
|
||||
])(
|
||||
"retains the first $label schema diagnostic through the file wrapper",
|
||||
@@ -60,8 +60,8 @@ describe.each([
|
||||
details: { reason: expect.stringContaining(`at ${field}:`) },
|
||||
});
|
||||
if (field === "target")
|
||||
expect(projected.details?.reason).toBe(
|
||||
"Analysis snapshot validation failed at target: Invalid input: expected object, received undefined (2 more issues)",
|
||||
expect(projected.details?.reason).toMatch(
|
||||
/ at target: .+ \(2 more issues\)$/,
|
||||
);
|
||||
expect(projected).not.toHaveProperty("cause");
|
||||
expect(projected).not.toHaveProperty("stack");
|
||||
|
||||
Reference in new issue
Block a user