busbar_sf_agentscript/graph/
error.rs1use super::nodes::Span;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum GraphBuildError {
9 #[error("Missing required element: {element}")]
11 MissingElement { element: String },
12
13 #[error("Duplicate {kind} definition: {name} at {span:?}")]
15 DuplicateDefinition {
16 kind: String,
17 name: String,
18 span: Span,
19 },
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum ValidationError {
25 UnresolvedReference {
27 reference: String,
29 namespace: String,
31 span: Span,
33 context: String,
35 },
36
37 CycleDetected {
39 path: Vec<String>,
41 },
42
43 UnreachableTopic {
45 name: String,
47 span: Span,
49 },
50
51 UnusedActionDef {
53 name: String,
55 topic: String,
57 span: Span,
59 },
60
61 UnusedVariable {
63 name: String,
65 span: Span,
67 },
68
69 UninitializedVariable {
71 name: String,
73 read_span: Span,
75 },
76
77 InvalidPropertyAccess {
79 reference: String,
81 variable: String,
83 variable_type: String,
85 span: Span,
87 },
88}
89
90impl ValidationError {
91 pub fn span(&self) -> Option<Span> {
93 match self {
94 ValidationError::UnresolvedReference { span, .. }
95 | ValidationError::UnreachableTopic { span, .. }
96 | ValidationError::UnusedActionDef { span, .. }
97 | ValidationError::UnusedVariable { span, .. }
98 | ValidationError::InvalidPropertyAccess { span, .. }
99 | ValidationError::UninitializedVariable {
100 read_span: span, ..
101 } => Some(*span),
102 ValidationError::CycleDetected { .. } => None,
103 }
104 }
105
106 pub fn message(&self) -> String {
108 match self {
109 ValidationError::UnresolvedReference {
110 reference, context, ..
111 } => {
112 format!("Unresolved reference '{}' in {}", reference, context)
113 }
114 ValidationError::CycleDetected { path } => {
115 format!("Cycle detected in topic transitions: {}", path.join(" -> "))
116 }
117 ValidationError::UnreachableTopic { name, .. } => {
118 format!("Topic '{}' is unreachable from start_agent", name)
119 }
120 ValidationError::UnusedActionDef { name, topic, .. } => {
121 format!("Action '{}' in topic '{}' is never invoked", name, topic)
122 }
123 ValidationError::UnusedVariable { name, .. } => {
124 format!("Variable '{}' is never read", name)
125 }
126 ValidationError::UninitializedVariable { name, .. } => {
127 format!("Variable '{}' is read but never written", name)
128 }
129 ValidationError::InvalidPropertyAccess {
130 reference,
131 variable,
132 variable_type,
133 ..
134 } => {
135 format!(
136 "Property access on '{}' is invalid: variable '{}' has type '{}', only 'object' supports property access",
137 reference, variable, variable_type
138 )
139 }
140 }
141 }
142
143 pub fn is_unresolved_reference(&self) -> bool {
145 matches!(self, ValidationError::UnresolvedReference { .. })
146 }
147
148 pub fn is_cycle(&self) -> bool {
150 matches!(self, ValidationError::CycleDetected { .. })
151 }
152
153 pub fn is_unused(&self) -> bool {
155 matches!(
156 self,
157 ValidationError::UnusedActionDef { .. } | ValidationError::UnusedVariable { .. }
158 )
159 }
160}