use nautilus_network::http::HttpClientError;
use thiserror::Error;
pub type LighterHttpResult<T> = Result<T, LighterHttpError>;
#[derive(Debug, Clone, Error)]
pub enum LighterHttpError {
#[error("network error: {0}")]
Network(String),
#[error("HTTP {status}: {body}")]
Http { status: u16, body: String },
#[error("rate limit exceeded: {0}")]
RateLimit(String),
#[error("venue error {code}: {message}")]
Venue { code: i64, message: String },
#[error("parse error: {0}")]
Parse(String),
}
impl From<HttpClientError> for LighterHttpError {
fn from(error: HttpClientError) -> Self {
Self::Network(error.to_string())
}
}
impl From<serde_json::Error> for LighterHttpError {
fn from(error: serde_json::Error) -> Self {
Self::Parse(error.to_string())
}
}
impl From<anyhow::Error> for LighterHttpError {
fn from(error: anyhow::Error) -> Self {
Self::Parse(error.to_string())
}
}
#[must_use]
pub fn should_retry_lighter_http_error(error: &LighterHttpError) -> bool {
match error {
LighterHttpError::Network(_) | LighterHttpError::RateLimit(_) => true,
LighterHttpError::Http { status, .. } => *status >= 500,
LighterHttpError::Venue { .. } | LighterHttpError::Parse(_) => false,
}
}
#[must_use]
pub fn create_lighter_http_timeout_error(msg: String) -> LighterHttpError {
LighterHttpError::Network(msg)
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case::network_retries(LighterHttpError::Network("dns failure".into()), true)]
#[case::rate_limit_retries(LighterHttpError::RateLimit("429".into()), true)]
#[case::server_5xx_retries(LighterHttpError::Http { status: 503, body: "busy".into() }, true)]
#[case::server_500_retries(LighterHttpError::Http { status: 500, body: "boom".into() }, true)]
#[case::client_400_does_not_retry(LighterHttpError::Http { status: 400, body: "bad".into() }, false)]
#[case::client_404_does_not_retry(LighterHttpError::Http { status: 404, body: "missing".into() }, false)]
#[case::venue_does_not_retry(LighterHttpError::Venue { code: 20001, message: "invalid".into() }, false)]
#[case::parse_does_not_retry(LighterHttpError::Parse("bad json".into()), false)]
fn test_should_retry_lighter_http_error(
#[case] error: LighterHttpError,
#[case] expected: bool,
) {
assert_eq!(should_retry_lighter_http_error(&error), expected);
}
}