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