mod private
{
use error_tools::dependency::thiserror;
use serde::{ Deserialize, Serialize };
#[ derive( Debug, thiserror::Error, Clone, PartialEq ) ]
pub enum Error
{
#[ error( "IO error : {0}" ) ]
Io( String ),
#[ error( "Request building error : {0}" ) ]
RequestBuilding( String ),
#[ error( "API error : {0}" ) ]
ApiError( String ),
#[ error( "Authentication error : {0}" ) ]
AuthenticationError( String ),
#[ error( "Rate limit exceeded : {0}" ) ]
RateLimitError( String ),
#[ error( "Invalid argument : {0}" ) ]
InvalidArgument( String ),
#[ error( "Server error : {0}" ) ]
ServerError( String ),
#[ error( "Serialization error : {0}" ) ]
SerializationError( String ),
#[ error( "Deserialization error : {0}" ) ]
DeserializationError( String ),
#[ error( "Network error : {0}" ) ]
NetworkError( String ),
#[ error( "Unknown error : {0}" ) ]
Unknown( String ),
#[ error( "Not implemented : {0}" ) ]
NotImplemented( String ),
#[ error( "Configuration error : {0}" ) ]
ConfigurationError( String ),
#[ error( "Timeout error : {0}" ) ]
TimeoutError( String ),
#[ error( "Resource not found : {0}" ) ]
NotFound( String ),
#[ error( "Health check error : {0}" ) ]
Health( String ),
#[ error( "Validation error : {message}" ) ]
ValidationError
{
message : String
},
#[ error( "Batch processing error : {successful} successful, {failed} failed - {message}" ) ]
BatchProcessingError
{
successful : usize,
failed : usize,
message : String
},
#[ cfg( feature = "circuit_breaker" ) ]
#[ error( "Circuit breaker is open : {0}" ) ]
CircuitBreakerOpen( String ),
#[ cfg( feature = "caching" ) ]
#[ error( "Cache error : {0}" ) ]
CacheError( String ),
#[ cfg( feature = "rate_limiting" ) ]
#[ error( "Rate limited : {0}" ) ]
RateLimited( String ),
#[ cfg( feature = "enterprise_quota" ) ]
#[ error( "Quota exceeded : {0}" ) ]
QuotaExceeded( String ),
}
impl From< std::io::Error > for Error
{
#[ inline ]
fn from( err : std::io::Error ) -> Self
{
Error::Io( err.to_string() )
}
}
impl From< serde_json::Error > for Error
{
#[ inline ]
fn from( err : serde_json::Error ) -> Self
{
Error::SerializationError( err.to_string() )
}
}
impl From< reqwest::Error > for Error
{
#[ inline ]
fn from( err : reqwest::Error ) -> Self
{
if err.is_timeout()
{
Error::TimeoutError( format!( "Request timeout : {err}" ) )
}
else if err.is_connect()
{
Error::NetworkError( format!( "Connection error : {err}" ) )
}
else if err.is_request()
{
Error::RequestBuilding( format!( "Request error : {err}" ) )
}
else if err.status() == Some( reqwest::StatusCode::NOT_FOUND )
{
Error::NotFound( format!( "Resource not found : {err}" ) )
}
else if err.status() == Some( reqwest::StatusCode::TOO_MANY_REQUESTS )
{
Error::RateLimitError( format!( "Rate limit exceeded : {err}" ) )
}
else
{
Error::NetworkError( err.to_string() )
}
}
}
#[ derive( Debug, Deserialize, Serialize ) ]
#[ serde( rename_all = "camelCase" ) ]
pub struct ApiErrorResponse
{
pub error : ApiErrorDetails,
}
#[ derive( Debug, Deserialize, Serialize ) ]
#[ serde( rename_all = "camelCase" ) ]
pub struct ApiErrorDetails
{
pub code : i32,
pub message : String,
pub status : Option< String >,
}
}
::mod_interface::mod_interface!
{
exposed use private::Error;
exposed use private::ApiErrorResponse;
exposed use private::ApiErrorDetails;
}