Repository navigation
Description
Background
Part of #277's rollout — the Foundation PR (#357, merged) built the MinigrafError/ErrorCategory/REGISTRY/bail_coded!/err_coded! machinery with zero call sites migrated. This issue is step 2 of that rollout: migrate src/query/datalog/parser.rs to real PRS-0xx codes (79 of the 130 documented codes in docs/ERROR_REFERENCE.md — the largest category).
Blocker to resolve first (discovered during #357's final review)
src/query/datalog/parser.rs is not anyhow-based — every parser function, including pub fn parse_datalog_command(input: &str) -> Result<DatalogCommand, String> (118 Err(...) returns across the file), returns Result<_, String>. bail_coded!/err_coded! expand to Err(anyhow::Error::new(CodedError::new(...))), which is a type error inside any Result<_, String>-returning function — they are not a drop-in replacement here the way they are in every other module.
Compounding it: src/db.rs's three call sites (Minigraf::execute, WriteTransaction::execute, Minigraf::prepare) each do parse_datalog_command(input).map_err(|e| anyhow::anyhow!("{}", e))? — even if the parser produced a coded error some other way, this stringifies it via Display, destroying the chain at exactly the boundary MinigrafError::from(anyhow::Error) depends on for code detection.
Must decide before planning this issue in detail — two options (see docs/superpowers/specs/2026-08-25-structured-error-codes-design.md, Migration phasing, step 2, for full writeup):
- (a) Change
parser.rs's error type toanyhow::Error(or aCodedError-carrying type) and drop the three stringifyingmap_errcalls indb.rs. Simpler, keeps one mechanism crate-wide. - (b) Add a parallel
String-flavored code-tagging mechanism forparser.rsspecifically. Avoids touching the parser's error type but permanently duplicates the tagging machinery.
Work item
Once the blocker is resolved: migrate all parser.rs call sites to carry their real PRS-0xx code (via bail_coded!/err_coded! or the chosen equivalent), and add regression tests asserting the specific code comes back from db.execute()/db.prepare() for each.
Activity