Skip to main content

stygian_graph/
domain.rs

1//! Domain layer - core business logic
2//!
3//! Contains pure business logic with no infrastructure dependencies.
4//! Domain layer only imports from ports (trait definitions), never from adapters.
5
6/// DAG execution engine using petgraph
7pub mod graph;
8
9/// Graph introspection types and queries
10pub mod introspection;
11
12/// Pipeline types with typestate pattern
13pub mod pipeline;
14
15/// Worker pool executor with backpressure
16pub mod executor;
17
18/// Idempotency tracking system
19pub mod idempotency;
20
21/// API discovery types (response shape, pagination, field inference)
22pub mod discovery;
23
24/// Domain error types
25pub mod error {
26    use thiserror::Error;
27
28    /// Primary error type for the stygian-graph crate
29    ///
30    /// Encompasses all domain-level errors following hexagonal architecture principles.
31    ///
32    /// # Example
33    ///
34    /// ```
35    /// use stygian_graph::domain::error::{StygianError, GraphError};
36    ///
37    /// fn validate_pipeline() -> Result<(), StygianError> {
38    ///     Err(StygianError::Graph(GraphError::CycleDetected))
39    /// }
40    /// ```
41    #[derive(Debug, Error)]
42    pub enum StygianError {
43        /// Graph execution errors
44        #[error("Graph error: {0}")]
45        Graph(#[from] GraphError),
46
47        /// Service interaction errors
48        #[error("Service error: {0}")]
49        Service(#[from] ServiceError),
50
51        /// AI provider errors
52        #[error("Provider error: {0}")]
53        Provider(#[from] ProviderError),
54
55        /// Configuration errors
56        #[error("Config error: {0}")]
57        Config(#[from] ConfigError),
58
59        /// Rate limiting errors
60        #[error("Rate limit error: {0}")]
61        RateLimit(#[from] RateLimitError),
62
63        /// Caching errors
64        #[error("Cache error: {0}")]
65        Cache(#[from] CacheError),
66    }
67
68    /// Graph-specific errors
69    #[derive(Debug, Error)]
70    pub enum GraphError {
71        /// Graph contains a cycle (DAG violation)
72        #[error("Graph contains cycle, cannot execute")]
73        CycleDetected,
74
75        /// Invalid node reference
76        #[error("Node not found: {0}")]
77        NodeNotFound(String),
78
79        /// Invalid edge configuration
80        #[error("Invalid edge: {0}")]
81        InvalidEdge(String),
82
83        /// Pipeline validation failed
84        #[error("Invalid pipeline: {0}")]
85        InvalidPipeline(String),
86
87        /// Execution failed
88        #[error("Execution failed: {0}")]
89        ExecutionFailed(String),
90    }
91
92    /// Service-level errors
93    #[derive(Debug, Error)]
94    pub enum ServiceError {
95        /// Service unavailable
96        #[error("Service unavailable: {0}")]
97        Unavailable(String),
98
99        /// Service timeout
100        #[error("Service timeout after {0}ms")]
101        Timeout(u64),
102
103        /// Service returned invalid response
104        #[error("Invalid response: {0}")]
105        InvalidResponse(String),
106
107        /// Service authentication failed
108        #[error("Authentication failed: {0}")]
109        AuthenticationFailed(String),
110
111        /// Service is rate-limiting; caller should retry after the given delay
112        #[error("Rate limited, retry after {retry_after_ms}ms")]
113        RateLimited {
114            /// Milliseconds to wait before retrying
115            retry_after_ms: u64,
116        },
117    }
118
119    /// AI provider errors
120    #[derive(Debug, Error)]
121    pub enum ProviderError {
122        /// Provider API error
123        #[error("API error: {0}")]
124        ApiError(String),
125
126        /// Invalid API key or credentials
127        #[error("Invalid credentials")]
128        InvalidCredentials,
129
130        /// Token limit exceeded
131        #[error("Token limit exceeded: {0}")]
132        TokenLimitExceeded(String),
133
134        /// Model not available
135        #[error("Model not available: {0}")]
136        ModelUnavailable(String),
137
138        /// Content policy violation
139        #[error("Content policy violation: {0}")]
140        ContentPolicyViolation(String),
141    }
142
143    /// Configuration errors
144    #[derive(Debug, Error)]
145    pub enum ConfigError {
146        /// Missing required configuration
147        #[error("Missing required config: {0}")]
148        MissingConfig(String),
149
150        /// Invalid configuration value
151        #[error("Invalid config value for '{key}': {reason}")]
152        InvalidValue {
153            /// Configuration key
154            key: String,
155            /// Reason for invalidity
156            reason: String,
157        },
158
159        /// Configuration file error
160        #[error("Config file error: {0}")]
161        FileError(String),
162
163        /// TOML parsing error
164        #[error("TOML parse error: {0}")]
165        ParseError(String),
166    }
167
168    /// Rate limiting errors
169    #[derive(Debug, Error)]
170    pub enum RateLimitError {
171        /// Rate limit exceeded
172        #[error("Rate limit exceeded: {0} requests per {1} seconds")]
173        Exceeded(u32, u32),
174
175        /// Quota exhausted
176        #[error("Quota exhausted: {0}")]
177        QuotaExhausted(String),
178
179        /// Retry after duration
180        #[error("Retry after {0} seconds")]
181        RetryAfter(u64),
182    }
183
184    /// Caching errors
185    #[derive(Debug, Error)]
186    pub enum CacheError {
187        /// Cache miss
188        #[error("Cache miss: {0}")]
189        Miss(String),
190
191        /// Cache write failed
192        #[error("Cache write failed: {0}")]
193        WriteFailed(String),
194
195        /// Cache read failed
196        #[error("Cache read failed: {0}")]
197        ReadFailed(String),
198
199        /// Cache eviction failed
200        #[error("Cache eviction failed: {0}")]
201        EvictionFailed(String),
202
203        /// Cache corrupted
204        #[error("Cache corrupted: {0}")]
205        Corrupted(String),
206    }
207
208    /// Domain result type using `StygianError`
209    pub type Result<T> = std::result::Result<T, StygianError>;
210
211    /// Legacy domain error (kept for backward compatibility)
212    #[derive(Debug, Error)]
213    pub enum DomainError {
214        /// Graph contains cycle
215        #[error("Graph contains cycle, cannot execute")]
216        CycleDetected,
217
218        /// Invalid pipeline configuration
219        #[error("Invalid pipeline: {0}")]
220        InvalidPipeline(String),
221
222        /// Execution failed
223        #[error("Execution failed: {0}")]
224        ExecutionFailed(String),
225
226        /// Service error
227        #[error("Service error: {0}")]
228        ServiceError(String),
229    }
230
231    /// Legacy domain result type
232    pub type DomainResult<T> = std::result::Result<T, DomainError>;
233}