Fix: Empty Module Paths in Error Catalog
Fixed a bug where all 68 error enums in the generated error catalog had empty "path": "" values, making the catalog useless for locating error types.
Context
The mando errors command generates a JSON error catalog by parsing rustdoc JSON output for three crates: mando_core, mando_lib, and mando_bess. The extractor lives in src/workspace/projects/treats/balazs_mando_error_extractor.rs.
Symptoms
- Running
mando errorsproduces a JSON catalog where every entry has"path": "" - All 68 error enums affected
- The enum names and variants were extracted correctly; only the module path was missing
Root Cause
The extractor looked up enum item IDs in rustdoc’s doc["paths"] map to resolve the fully-qualified module path. However, rustdoc’s paths map does not include private or pub(crate) items, even when generating docs with --document-private-items. Since most error enums in the Mando workspace are pub(crate), their IDs were absent from paths, and the lookup returned null for every one of them.
Rustdoc Gotcha
--document-private-itemscauses rustdoc to emit private items into the JSON output (theindexmap), but it does not add them to thepathsmap. Thepathsmap only contains items that are publicly reachable. This is an undocumented (or poorly documented) behavior as of Rust 1.88.0.
Fix
Added a fallback path-derivation strategy that activates when the paths lookup fails. The fallback derives the module path from the source file location (span.filename) stored on each item in the rustdoc index.
Two new helpers added to balazs_mando_error_extractor.rs:
crate_name_from_root()— extracts the crate name from a--crate-rootpathderive_module_path()— converts a source file path into a Rust module path:- Strip the crate directory and
src/prefix - Strip the
.rsextension - Handle special files:
lib.rsandmod.rsmap to their parent directory - Convert
/separators to:: - Prepend the crate name
- Append the enum name
- Strip the crate directory and
Example derivation:
span.filename: "mando-lib/src/adapter/alpiq/error.rs"
crate root: "mando-lib/"
→ strip prefix: "adapter/alpiq/error.rs"
→ strip .rs: "adapter/alpiq/error"
→ convert /: "adapter::alpiq::error"
→ prepend crate: "mando_lib::adapter::alpiq::error"
→ append enum: "mando_lib::adapter::alpiq::error::AlpiqError"
Tests
4 new unit tests covering the fallback logic:
- Standard nested module path derivation
lib.rsat crate rootmod.rsin a subdirectory- Crate name extraction from root path
Related
- mando-cli
- mando-lib-macro (provides
#[derive(ErrorCode)]that the catalog documents)