pub enum HttpError {
ClientCreation {
reason: String,
},
RequestFailed {
url: String,
reason: String,
},
Timeout {
url: String,
seconds: u64,
},
RateLimited {
retry_after_seconds: u64,
},
InvalidResponse {
expected: String,
actual: String,
},
}Expand description
HTTP-related errors with detailed context for network operations.
This enum provides comprehensive error classification for HTTP operations throughout the application, including Azure API calls, authentication requests, and other network operations. Each error variant includes relevant context to aid in debugging and error handling.
§Error Categories
§Client Configuration Errors
ClientCreation- HTTP client initialization failures
§Request Execution Errors
RequestFailed- General request failures with URL and reasonTimeout- Request timeout with duration and target URLInvalidResponse- Unexpected response format or content
§Rate Limiting and Service Errors
RateLimited- Rate limiting with retry timing information
§Examples
§Basic Error Handling
use quetty_server::common::errors::HttpError;
async fn handle_http_error(error: HttpError) {
match error {
HttpError::Timeout { url, seconds } => {
eprintln!("Request to {} timed out after {}s", url, seconds);
// Implement retry with longer timeout
}
HttpError::RateLimited { retry_after_seconds } => {
println!("Rate limited. Retrying after {}s", retry_after_seconds);
// Wait and retry
}
HttpError::RequestFailed { url, reason } => {
eprintln!("Request to {} failed: {}", url, reason);
// Log and handle specific failure
}
HttpError::ClientCreation { reason } => {
eprintln!("Failed to create HTTP client: {}", reason);
// Reinitialize client with different configuration
}
HttpError::InvalidResponse { expected, actual } => {
eprintln!("Invalid response: expected {}, got {}", expected, actual);
// Handle unexpected response format
}
}
}§Retry Logic Implementation
use quetty_server::common::errors::HttpError;
use std::time::Duration;
use tokio::time::sleep;
async fn http_request_with_retry<T>(
request_fn: impl Fn() -> Result<T, HttpError>
) -> Result<T, HttpError> {
let mut attempts = 0;
let max_attempts = 3;
loop {
attempts += 1;
match request_fn() {
Ok(result) => return Ok(result),
Err(HttpError::RateLimited { retry_after_seconds }) => {
if attempts < max_attempts {
sleep(Duration::from_secs(retry_after_seconds)).await;
continue;
}
return Err(HttpError::RateLimited { retry_after_seconds });
}
Err(HttpError::Timeout { url, seconds }) => {
if attempts < max_attempts {
// Exponential backoff for timeouts
sleep(Duration::from_secs(2_u64.pow(attempts))).await;
continue;
}
return Err(HttpError::Timeout { url, seconds });
}
Err(other) => return Err(other), // Don't retry client errors
}
}
}§Azure API Error Handling
use quetty_server::common::errors::HttpError;
async fn call_azure_api(endpoint: &str) -> Result<String, HttpError> {
// Simulated Azure API call
match make_request(endpoint).await {
Ok(response) => Ok(response),
Err(e) => {
// Convert to structured HttpError
Err(HttpError::RequestFailed {
url: endpoint.to_string(),
reason: e.to_string(),
})
}
}
}
// Usage with error context
let result = call_azure_api("https://management.azure.com/subscriptions").await;
match result {
Ok(data) => println!("API call successful: {}", data),
Err(HttpError::RequestFailed { url, reason }) => {
if reason.contains("401") {
// Handle authentication error
println!("Authentication required for {}", url);
} else if reason.contains("404") {
// Handle resource not found
println!("Resource not found: {}", url);
} else {
// Handle other errors
println!("Request failed: {} - {}", url, reason);
}
}
Err(other) => {
println!("HTTP error: {}", other);
}
}§Integration Patterns
§Error Conversion
This error type is designed to be easily converted to higher-level error types:
use quetty_server::common::errors::HttpError;
use quetty_server::service_bus_manager::ServiceBusError;
impl From<HttpError> for ServiceBusError {
fn from(http_error: HttpError) -> Self {
match http_error {
HttpError::Timeout { .. } => ServiceBusError::OperationTimeout(http_error.to_string()),
HttpError::RateLimited { .. } => ServiceBusError::OperationTimeout(http_error.to_string()),
_ => ServiceBusError::ConnectionFailed(http_error.to_string()),
}
}
}§Logging Integration
use quetty_server::common::errors::HttpError;
fn log_http_error(error: &HttpError) {
match error {
HttpError::RequestFailed { url, reason } => {
log::error!("HTTP request failed: url={}, reason={}", url, reason);
}
HttpError::Timeout { url, seconds } => {
log::warn!("HTTP request timeout: url={}, duration={}s", url, seconds);
}
HttpError::RateLimited { retry_after_seconds } => {
log::info!("HTTP rate limited: retry_after={}s", retry_after_seconds);
}
_ => {
log::error!("HTTP error: {}", error);
}
}
}Variants§
ClientCreation
HTTP client initialization failed.
This error occurs when creating or configuring the HTTP client fails, typically due to invalid configuration, SSL/TLS setup issues, or system resource constraints.
§Fields
reason: Detailed description of the client creation failure
§Recovery
- Validate HTTP client configuration
- Check system resources and network settings
- Retry with alternative client configuration
RequestFailed
HTTP request execution failed.
This is a general request failure that can occur due to various reasons including network issues, server errors, authentication problems, or malformed requests.
§Fields
url: The URL that was being requestedreason: Detailed description of the failure
§Recovery
- Check network connectivity
- Validate request parameters and authentication
- Implement retry logic for transient failures
Timeout
HTTP request timed out.
This error occurs when a request takes longer than the configured timeout duration. This can happen due to slow network conditions, overloaded servers, or network connectivity issues.
§Fields
url: The URL that timed outseconds: The timeout duration that was exceeded
§Recovery
- Retry with longer timeout
- Check network connectivity
- Consider alternative endpoints if available
RateLimited
Rate limiting is active for HTTP requests.
This error occurs when the server has rate-limited the client due to too many requests in a short period. The server provides guidance on when to retry.
§Fields
retry_after_seconds: Duration to wait before retrying
§Recovery
- Wait for the specified duration before retrying
- Implement request throttling to prevent future rate limiting
- Consider using exponential backoff for subsequent requests
InvalidResponse
Received response doesn’t match expected format.
This error occurs when the server returns a response that doesn’t match the expected format, content type, or structure. This can indicate API changes, server errors, or client-side parsing issues.
§Fields
expected: Description of what was expectedactual: Description of what was actually received
§Recovery
- Validate API endpoint and version compatibility
- Check response parsing logic
- Consider graceful degradation for unexpected responses
Trait Implementations§
Source§impl Error for HttpError
impl Error for HttpError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
Auto Trait Implementations§
impl Freeze for HttpError
impl RefUnwindSafe for HttpError
impl Send for HttpError
impl Sync for HttpError
impl Unpin for HttpError
impl UnwindSafe for HttpError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.