Found while investigating #1731
While root-causing #1731 (file_hashes/edges coupling), I found a broader, distinct robustness gap in the native (Rust) build pipeline: several edge-writing functions swallow their own DB errors instead of propagating them, so run_pipeline can return Ok(...) (and the JS caller sees a "successful" build) even when edges were never written for some or all files.
Concrete evidence in crates/codegraph-core/src/domain/graph/builder/:
stages/import_edges.rs::insert_edges — on conn.unchecked_transaction() failure, does eprintln!(...); return; from a function returning (). The caller (pipeline.rs Stage 7) has no way to know this happened.
pipeline.rs — build_and_insert_call_edges(conn, &file_symbols, &import_ctx, ...) is called without capturing/checking its return value at all.
pipeline.rs Stage 5 — let _ = insert_nodes::do_insert_nodes(conn, &insert_batches, &change_result.removed); explicitly discards the Result.
None of these failures bubble up through run_pipeline's Result<BuildPipelineResult, String>, so NativeDatabase::build_graph() (the napi entry point) returns success to JS even when a transaction failed to start (e.g. transient SQLITE_BUSY under WAL contention, which this codebase's own dual-connection dance can plausibly trigger). The only observable symptom is an eprintln! to stderr that most callers never see.
This is a different bug from #1731 (which was about timing — file_hashes committed before edges even had a chance to run). This one is about error visibility — even when the pipeline tries to write edges and fails, nothing tells the caller. Combined with file_hashes semantics (fixed in #1731 by deferring the hash commit past edge-building), a silent edge-write failure here would still leave file_hashes un-advanced on retry (self-healing), but the current build's result would incorrectly report success with incomplete data, and users get no diagnostic beyond an easily-missed stderr line.
Suggested fix (not done here — separate concern)
Thread Result (or at least abool/error-count) from insert_edges, build_and_insert_call_edges, and the Stage 5 do_insert_nodes call up through run_pipeline, so a transaction-start failure surfaces as a thrown JS error (matching how other stages already do via ?) instead of a silently-successful build.
Not fixing this now because it requires restructuring return types across several Rust functions — a larger, separate change from #1731's scope.
Found while investigating #1731
While root-causing #1731 (file_hashes/edges coupling), I found a broader, distinct robustness gap in the native (Rust) build pipeline: several edge-writing functions swallow their own DB errors instead of propagating them, so
run_pipelinecan returnOk(...)(and the JS caller sees a "successful" build) even when edges were never written for some or all files.Concrete evidence in
crates/codegraph-core/src/domain/graph/builder/:stages/import_edges.rs::insert_edges— onconn.unchecked_transaction()failure, doeseprintln!(...); return;from a function returning(). The caller (pipeline.rsStage 7) has no way to know this happened.pipeline.rs—build_and_insert_call_edges(conn, &file_symbols, &import_ctx, ...)is called without capturing/checking its return value at all.pipeline.rsStage 5 —let _ = insert_nodes::do_insert_nodes(conn, &insert_batches, &change_result.removed);explicitly discards theResult.None of these failures bubble up through
run_pipeline'sResult<BuildPipelineResult, String>, soNativeDatabase::build_graph()(the napi entry point) returns success to JS even when a transaction failed to start (e.g. transientSQLITE_BUSYunder WAL contention, which this codebase's own dual-connection dance can plausibly trigger). The only observable symptom is aneprintln!to stderr that most callers never see.This is a different bug from #1731 (which was about timing — file_hashes committed before edges even had a chance to run). This one is about error visibility — even when the pipeline tries to write edges and fails, nothing tells the caller. Combined with file_hashes semantics (fixed in #1731 by deferring the hash commit past edge-building), a silent edge-write failure here would still leave file_hashes un-advanced on retry (self-healing), but the current build's result would incorrectly report success with incomplete data, and users get no diagnostic beyond an easily-missed stderr line.
Suggested fix (not done here — separate concern)
Thread
Result(or at least abool/error-count) frominsert_edges,build_and_insert_call_edges, and the Stage 5do_insert_nodescall up throughrun_pipeline, so a transaction-start failure surfaces as a thrown JS error (matching how other stages already do via?) instead of a silently-successful build.Not fixing this now because it requires restructuring return types across several Rust functions — a larger, separate change from #1731's scope.