Skip to content

feat(pm): show require-by chain on dependency resolution failure#2804

Merged
elrrrrrrr merged 5 commits intonextfrom
feat/pm-resolve-error-chain
Apr 17, 2026
Merged

feat(pm): show require-by chain on dependency resolution failure#2804
elrrrrrrr merged 5 commits intonextfrom
feat/pm-resolve-error-chain

Conversation

@elrrrrrrr
Copy link
Copy Markdown
Contributor

Summary

When ut install fails to resolve a transitive dep, the error previously showed only the failing package name — making it hard to find which of your declared dependencies pulled it in. This PR augments ResolveError with a dependency chain so the output now looks like:

ERROR Dependency resolution failed: Registry error: Failed to fetch @react-pdf/svg@^1.1.0: HTTP 404

required by:
  @lobehub/lobehub@2.1.48
  └── @react-pdf/image@3.1.0
      └── @react-pdf/svg@^1.1.0

Design

  • DependencyGraph::logical_ancestry(node) walks the logical require-by chain (via resolved DependencyEdge.to), not the physical install tree. With npm hoisting the physical tree is mostly flat under root, so a physical walk would hide the real introducers.
  • Built lazily on error paths only (error is already aborting resolution, so O(N+E) scan is acceptable).
  • New ResolveError::WithChain { chain, source } variant, formatted in Display with a tree-style rendering that mirrors ut list.

Test plan

  • cargo test -p utoo-ruborist — 160 tests pass, includes test_logical_ancestry_traces_hoisted_chain (sets up logical root→A→B→C with all three flat-hoisted physically, asserts the reported chain is [root, A, B, C]) and test_with_chain_display_renders_tree
  • cargo clippy -p utoo-ruborist -p utoo-pm --all-targets -D warnings --no-deps — clean
  • cargo fmt --check — clean
  • Manual smoke test against a real failing install (e.g. lobehub with a 404'd dep)

🤖 Generated with Claude Code

When `ut install` fails to resolve a transitive dep, the error now
includes the logical chain (root → ... → failing dep) so users can
see which package pulled in the missing/broken dependency, rather
than just the name of the failing package.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces logical dependency ancestry tracing to improve error reporting during package resolution. It adds a logical_ancestry method to the DependencyGraph to reconstruct the 'required by' chain and updates the ResolveError enum to include this chain, enabling a tree-like visualization of the dependency path in error messages. I have no feedback to provide.

elrrrrrrr and others added 4 commits April 17, 2026 15:40
Per review feedback — the tree-drawing belongs in the CLI layer (like
ut list's `print_dep_tree` in cmd/list.rs), not in the library's error
Display impl.

- ruborist: `ResolveError::WithChain`'s Display now delegates to the
  wrapped source; the `chain` field is structured data only.
- ruborist/api: preserve the typed error through anyhow via
  `Error::new + context` so downstream can downcast.
- pm/util/format_print: new `format_resolve_chain` helper that scans
  the anyhow cause chain for `ResolveError::WithChain` and renders a
  tree with box characters.
- pm/main: on error, prepend the decorated tree when present.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- build_requester_index: replace nested node/edge loops with a single
  pass over edge_references() and a let-chain filter.
- logical_ancestry: replace the imperative walk (mutable current,
  visited, chain + multi-break while) with iter::successors + scan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- build_requester_index: switch to early-continue (let-else) style so
  no statement sits deeper than the for-loop body.
- logical_ancestry walker: replace if/else with Option::filter for a
  one-line predicate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@elrrrrrrr elrrrrrrr added the A-Pkg Manager Area: Package Manager label Apr 17, 2026
@elrrrrrrr elrrrrrrr marked this pull request as ready for review April 17, 2026 08:26
@elrrrrrrr elrrrrrrr merged commit 07cfc34 into next Apr 17, 2026
27 checks passed
@elrrrrrrr elrrrrrrr deleted the feat/pm-resolve-error-chain branch April 17, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Pkg Manager Area: Package Manager

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants