Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/review/rag-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async function fetchRepoTree(env: Env, repoFullName: string, ref: string, token:
}
return entries;
} catch (error) {
console.log(JSON.stringify({ ev: "rag_index_tree_error", repo: repoFullName, message: String(error).slice(0, 200) }));
console.error(JSON.stringify({ level: "error", event: "rag_index_tree_error", ev: "rag_index_tree_error", repo: repoFullName, message: String(error).slice(0, 200) }));
return null;
}
}
Expand Down Expand Up @@ -178,7 +178,7 @@ async function listStoredChunkPaths(infra: ReturnType<typeof createReviewAdapter
.all<{ path: string }>();
return (rows.results ?? []).map((row) => row.path).filter((path) => typeof path === "string" && path.length > 0);
} catch (error) {
console.log(JSON.stringify({ ev: "rag_list_paths_error", project, repo, message: String(error).slice(0, 200) }));
console.error(JSON.stringify({ level: "error", event: "rag_list_paths_error", ev: "rag_list_paths_error", project, repo, message: String(error).slice(0, 200) }));
return [];
}
}
Expand Down
12 changes: 10 additions & 2 deletions test/unit/rag-index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,23 @@ describe("indexRepo: full repo index (tree → chunk → embed → upsert)", ()
expect(vec.upserted.length).toBe(0);
});

it("a tree fetch that THROWS degrades to nothing indexed (fetchRepoTree catch arm)", async () => {
it("a tree fetch that THROWS degrades to nothing indexed (fetchRepoTree catch arm) + surfaces it at ERROR for Sentry (#5)", async () => {
const { env, vec } = indexEnv();
const errSpy = vi.spyOn(console, "error").mockImplementation(() => {});
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
if (input.toString().includes("/git/trees/")) throw new Error("network down");
return new Response("missing", { status: 404 });
});
await expect(indexRepo(env, PROJECT, REPO)).resolves.toEqual({ indexed: 0, files: 0, capped: false });
expect(vec.upserted.length).toBe(0);
// A broken RAG index-population (tree fetch) now surfaces at level:error → captured by the central Sentry forwarder.
expect(errSpy.mock.calls.some((c) => String(c[0]).includes("rag_index_tree_error") && String(c[0]).includes('"level":"error"'))).toBe(true);
errSpy.mockRestore();
});

it("a storage error while listing stored paths is fail-safe (prunes nothing, still indexes)", async () => {
it("a storage error while listing stored paths is fail-safe (prunes nothing, still indexes) + surfaces it at ERROR for Sentry (#5)", async () => {
const { env } = indexEnv();
const errSpy = vi.spyOn(console, "error").mockImplementation(() => {});
// Make ONLY the listStoredChunkPaths SELECT throw; everything else uses the real test D1.
const realPrepare = env.DB.prepare.bind(env.DB);
env.DB.prepare = ((query: string) =>
Expand All @@ -198,6 +203,9 @@ describe("indexRepo: full repo index (tree → chunk → embed → upsert)", ()
// The list failed → [] → nothing pruned, but the current file still indexes (fail-safe).
expect(result.files).toBe(1);
expect(await pathsFor(env, PROJECT, "gittensory")).toContain("src/current.ts");
// A broken stored-paths read now surfaces at level:error → captured by the central Sentry forwarder.
expect(errSpy.mock.calls.some((c) => String(c[0]).includes("rag_list_paths_error") && String(c[0]).includes('"level":"error"'))).toBe(true);
errSpy.mockRestore();
});

it("listStoredChunkPaths drops blank paths and tolerates an absent result set (defensive branches)", async () => {
Expand Down
Loading