pedant_graph/error.rs
1//! Why a graph build refused.
2//!
3//! Every variant names the exact join or ceiling that failed. No refusal
4//! returns a partial graph, none panics, and none exposes the snapshot identity
5//! bytes it compared.
6
7use crate::limits::GraphCollection;
8
9/// A refusal taken while projecting one resolution into a graph.
10#[derive(Debug, thiserror::Error)]
11pub enum GraphBuildError {
12 /// The supplied snapshot and resolution were requested for other targets.
13 #[error("the snapshot and the resolution describe different root targets")]
14 RootTargetMismatch,
15 /// The supplied snapshot is not the one the resolution was validated
16 /// against, even though both name the same root target.
17 #[error("the snapshot is not the one this resolution was validated against")]
18 SnapshotFingerprintMismatch,
19 /// A report unit has no graph container, or no source scope beneath one.
20 #[error("unit {unit} has no binding in this resolution")]
21 MissingUnitBinding {
22 /// The report-local unit identifier that no binding answers for.
23 unit: u32,
24 },
25 /// A report unit is bound to a build unit the supplied snapshot does not
26 /// hold, which is a binding that names nothing rather than a missing one.
27 #[error("unit {unit} is bound to a build unit this snapshot does not hold")]
28 DanglingUnitBinding {
29 /// The report-local unit identifier whose binding names nothing.
30 unit: u32,
31 },
32 /// Two report units are bound to one build unit, so one unit-qualified
33 /// source would have two owners.
34 #[error("report units {held} and {unit} are bound to one build unit")]
35 SharedUnitBinding {
36 /// The report-local unit identifier that bound the build unit first.
37 held: u32,
38 /// The report-local unit identifier that bound it again.
39 unit: u32,
40 },
41 /// One planned unit was given two container nodes, so everything it holds
42 /// would be rooted at whichever was bound last.
43 #[error("unit {unit} is already rooted at node {container}")]
44 RepeatedUnitContainer {
45 /// The plan-local unit position bound a second time.
46 unit: u32,
47 /// The container node that unit already took.
48 container: u32,
49 },
50 /// A report unit states no declaration this projection can root it at.
51 ///
52 /// A unit whose container is named by its own sources — a Go package
53 /// clause, and not a manifest — has no node at all when the report states
54 /// no such declaration for it.
55 #[error("unit {unit} states no declaration this projection roots it at")]
56 MissingUnitDeclaration {
57 /// The report-local unit identifier that declares no container.
58 unit: u32,
59 },
60 /// A report unit states more than one declaration of its own container.
61 #[error("unit {unit} states more than one container declaration")]
62 RepeatedUnitDeclaration {
63 /// The report-local unit identifier that declares two containers.
64 unit: u32,
65 },
66 /// Two planned units name one node as the root of their own trees.
67 #[error("node {root} roots more than one unit")]
68 SharedUnitRoot {
69 /// The node claimed as a root twice.
70 root: u32,
71 },
72 /// A snapshot dependency edge names a build unit with no graph container.
73 #[error(
74 "dependency edge {edge} ({alias}) names a build unit this graph holds no container for"
75 )]
76 MissingDependencyUnit {
77 /// The edge's position among the snapshot's dependency edges.
78 edge: u32,
79 /// The namespace-local name that edge declares its target under.
80 alias: Box<str>,
81 },
82 /// A stated site names a source the bound unit does not instantiate.
83 #[error("unit {unit} instantiates no source at {path}")]
84 MissingSourceNode {
85 /// The report-local unit identifier the site belongs to.
86 unit: u32,
87 /// The normalized repository-relative path the site named.
88 path: Box<str>,
89 },
90 /// One report unit instantiates one normalized path twice, so a second file
91 /// node would be minted for a source that already holds one.
92 #[error("unit {unit} instantiates the source at {path} more than once")]
93 RepeatedUnitSource {
94 /// The report-local unit identifier that instantiates it twice.
95 unit: u32,
96 /// The normalized repository-relative path stated more than once.
97 path: Box<str>,
98 },
99 /// The report states a different number of references and resolution
100 /// records, so no pairing between them is stated at all.
101 #[error("the report states {references} references and {records} resolution records")]
102 ReferenceRecordMismatch {
103 /// How many references the report states.
104 references: u32,
105 /// How many resolution records the report states.
106 records: u32,
107 },
108 /// A stated join names a definition this graph holds no node for.
109 #[error("definition {definition} has no node in this graph")]
110 MissingDefinitionNode {
111 /// The report-local definition identifier that named nothing.
112 definition: u32,
113 },
114 /// A report definition states a kind the adapter reading it has no node
115 /// for.
116 ///
117 /// The shared report vocabulary carries every language's kinds. Each
118 /// language's resolution is validated against its own subset before it is
119 /// published, so this refusal answers a report that reached the projection
120 /// without that validation rather than a repository that declares something
121 /// new.
122 #[error("definition {definition} states a kind this projection does not name")]
123 UnnamedDefinitionKind {
124 /// The report-local definition identifier whose kind has no node.
125 definition: u32,
126 },
127 /// A report reference states a kind the adapter reading it has no record
128 /// for.
129 #[error("reference {reference} states a kind this projection does not name")]
130 UnnamedReferenceKind {
131 /// The report-local reference identifier whose kind has no record.
132 reference: u32,
133 },
134 /// An edge was produced for a reference record this graph does not hold.
135 #[error("reference {reference} has no record in this graph")]
136 MissingReferenceRecord {
137 /// The reference identity that answers for no record.
138 reference: u32,
139 },
140 /// A containment edge names a node this graph holds no record for.
141 #[error("containment names node {node}, which this graph holds no record for")]
142 UnknownContainmentNode {
143 /// The node identity the containment relation named.
144 node: u32,
145 },
146 /// One node is contained by more than one parent.
147 #[error("node {child} is contained by more than one parent, including {parent}")]
148 MultiplyContained {
149 /// One parent the child is contained by.
150 parent: u32,
151 /// The multiply-contained child.
152 child: u32,
153 },
154 /// One node below the unit roots is contained by nothing.
155 #[error("node {node} is contained by no parent and is not a unit root")]
156 UnparentedNode {
157 /// The node no containment edge claims.
158 node: u32,
159 },
160 /// One unit root is contained by another node.
161 #[error("unit root {root} is contained by node {parent}")]
162 RootHasParent {
163 /// The unit root that must own itself.
164 root: u32,
165 /// The node that claims it.
166 parent: u32,
167 },
168 /// One containment chain returns to a node it already visited.
169 #[error("node {node} contains itself through its own ancestors")]
170 ContainmentCycle {
171 /// The node the chain returned to.
172 node: u32,
173 },
174 /// One collection reached its configured ceiling.
175 #[error("the {collection} collection cannot exceed {limit} entries")]
176 CapacityExceeded {
177 /// Which collection refused the insertion.
178 collection: GraphCollection,
179 /// The ceiling that collection is bounded by.
180 limit: u32,
181 },
182}