ErrorContext

Struct ErrorContext 

Source
pub struct ErrorContext {
    pub provider: String,
    pub endpoint: String,
    pub request_id: Option<String>,
    pub timestamp: DateTime<Utc>,
    pub retry_count: u32,
    pub suggested_action: SuggestedAction,
}
Expand description

Context information for error tracking

Fields§

§provider: String

AI provider that generated the error

§endpoint: String

API endpoint that was called

§request_id: Option<String>

Request ID for tracking

§timestamp: DateTime<Utc>

Timestamp when the error occurred

§retry_count: u32

Number of retry attempts

§suggested_action: SuggestedAction

Suggested action to take

Implementations§

Source§

impl ErrorContext

Source

pub fn new(provider: String, endpoint: String) -> Self

Create a new error context

Examples found in repository?
examples/resilience_example.rs (line 153)
140async fn demonstrate_error_handling() -> Result<(), Box<dyn std::error::Error>> {
141    let error_manager = ErrorRecoveryManager::new();
142    
143    // Simulate different types of errors
144    let errors = vec![
145        ("Rate Limit", ai_lib::types::AiLibError::RateLimitExceeded("API rate limit exceeded".to_string())),
146        ("Network", ai_lib::types::AiLibError::NetworkError("Connection timeout".to_string())),
147        ("Authentication", ai_lib::types::AiLibError::AuthenticationError("Invalid API key".to_string())),
148        ("Context Length", ai_lib::types::AiLibError::ContextLengthExceeded("Request too long".to_string())),
149    ];
150    
151    println!("Error Handling and Pattern Analysis:");
152    for (error_type, error) in errors {
153        let context = ErrorContext::new("demo_provider".to_string(), "/demo/endpoint".to_string());
154        let result = error_manager.handle_error(&error, &context).await;
155        
156        println!("  {} Error: {}", error_type, error);
157        println!("    Suggested Action: {:?}", context.suggested_action);
158        println!("    Recovery Result: {}", if result.is_ok() { "Success" } else { "Failed" });
159    }
160    
161    // Show error statistics
162    let stats = error_manager.get_error_statistics();
163    println!("\nError Statistics:");
164    println!("  Total Errors: {}", stats.total_errors);
165    println!("  Unique Error Types: {}", stats.unique_error_types);
166    println!("  Most Common: {:?}", stats.most_common_error);
167    
168    // Show error patterns
169    let patterns = error_manager.get_error_patterns();
170    for (error_type, pattern) in patterns {
171        println!("  {:?}: {} occurrences, {:.2} errors/min", 
172                error_type, pattern.count, pattern.frequency);
173    }
174    
175    Ok(())
176}
177
178async fn demonstrate_integrated_resilience() -> Result<(), Box<dyn std::error::Error>> {
179    // Create all resilience components
180    let circuit_breaker = CircuitBreaker::new(CircuitBreakerConfig::development());
181    let rate_limiter = TokenBucket::new(RateLimiterConfig::development());
182    let error_manager = ErrorRecoveryManager::new();
183    
184    println!("Integrated Resilience Components:");
185    println!("  Circuit Breaker: {:?}", circuit_breaker.state());
186    println!("  Rate Limiter: {:.1}% success rate", rate_limiter.success_rate());
187    println!("  Error Manager: {} total errors", error_manager.get_error_statistics().total_errors);
188    
189    // Simulate a resilient operation
190    println!("\nSimulating resilient operation:");
191    for i in 1..=5 {
192        println!("  Operation {}:", i);
193        
194        // Step 1: Rate limiting
195        match rate_limiter.acquire(1).await {
196            Ok(_) => println!("    ✅ Rate limit passed"),
197            Err(e) => {
198                println!("    ❌ Rate limited: {}", e);
199                continue;
200            }
201        }
202        
203        // Step 2: Circuit breaker protection
204        let result = circuit_breaker.call(async {
205            // Simulate API call with occasional failures
206            if i % 4 == 0 {
207                Err(ai_lib::types::AiLibError::ProviderError("Simulated provider error".to_string()))
208            } else {
209                Ok(format!("API response {}", i))
210            }
211        }).await;
212        
213        // Step 3: Error handling
214        match result {
215            Ok(response) => {
216                println!("    ✅ Success: {}", response);
217                rate_limiter.adjust_rate(true);
218            }
219            Err(e) => {
220                println!("    ❌ Failed: {}", e);
221                rate_limiter.adjust_rate(false);
222                
223                // Convert CircuitBreakerError to AiLibError for error manager
224                let ai_error = match e {
225                    CircuitBreakerError::Underlying(err) => err,
226                    CircuitBreakerError::CircuitOpen(msg) => ai_lib::types::AiLibError::ProviderError(msg),
227                    CircuitBreakerError::RequestTimeout(msg) => ai_lib::types::AiLibError::TimeoutError(msg),
228                    CircuitBreakerError::Disabled => ai_lib::types::AiLibError::ConfigurationError("Circuit breaker disabled".to_string()),
229                };
230                
231                let context = ErrorContext::new("demo_provider".to_string(), "/demo/endpoint".to_string());
232                let _ = error_manager.handle_error(&ai_error, &context).await;
233            }
234        }
235        
236        // Show current state
237        println!("    State: CB={:?}, RL={:.1}%", 
238                circuit_breaker.state(), rate_limiter.success_rate());
239    }
240    
241    Ok(())
242}
Source

pub fn with_retry(self, retry_count: u32) -> Self

Create error context with retry information

Source

pub fn with_request_id(self, request_id: String) -> Self

Create error context with request ID

Trait Implementations§

Source§

impl Clone for ErrorContext

Source§

fn clone(&self) -> ErrorContext

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ErrorContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ErrorContext

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for ErrorContext

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,