use std::io;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("HTTP protocol error: {0}")]
HttpProtocol(String),
#[error("HTTP {status}: {message}")]
HttpStatus { status: u16, message: String },
#[error("Redirect limit exceeded ({count} redirects)")]
RedirectLimit { count: u32 },
#[error("Invalid redirect URL: {0}")]
InvalidRedirectUrl(String),
#[error("Cookie parse error: {0}")]
CookieParse(String),
#[error("Decompression error: {0}")]
Decompression(String),
#[error("URL parse error: {0}")]
UrlParse(#[from] url::ParseError),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("URL encoding error: {0}")]
UrlEncode(#[from] serde_urlencoded::ser::Error),
#[error("IO error: {0}")]
Io(#[from] io::Error),
#[error("Missing required: {0}")]
Missing(String),
#[error("Operation timed out: {0}")]
Timeout(String),
#[error("Connect timeout after {0:?}")]
ConnectTimeout(std::time::Duration),
#[error("TTFB timeout after {0:?} - server did not respond with headers")]
TtfbTimeout(std::time::Duration),
#[error("Read idle timeout after {0:?} - stream may be hung")]
ReadIdleTimeout(std::time::Duration),
#[error("Write idle timeout after {0:?}")]
WriteIdleTimeout(std::time::Duration),
#[error("Total request deadline exceeded after {0:?}")]
TotalTimeout(std::time::Duration),
#[error("Pool acquire timeout after {0:?} - no connections available")]
PoolAcquireTimeout(std::time::Duration),
#[error("Connection error: {0}")]
Connection(String),
#[error("TLS error: {0}")]
Tls(String),
#[error("QUIC error: {0}")]
Quic(String),
#[error("SETTINGS_TIMEOUT (0x04): No SETTINGS frame received within {0:?}")]
SettingsTimeout(std::time::Duration),
}
impl Error {
pub fn http_status(status: u16, message: impl Into<String>) -> Self {
Self::HttpStatus {
status,
message: message.into(),
}
}
pub fn missing(field: impl Into<String>) -> Self {
Self::Missing(field.into())
}
pub fn io(message: impl Into<String>) -> Self {
Self::Io(io::Error::other(message.into()))
}
pub fn http_protocol(message: impl Into<String>) -> Self {
Self::HttpProtocol(message.into())
}
pub fn connection(message: impl Into<String>) -> Self {
Self::Connection(message.into())
}
pub fn timeout(message: impl Into<String>) -> Self {
Self::Timeout(message.into())
}
pub fn tls(message: impl Into<String>) -> Self {
Self::Tls(message.into())
}
pub fn quic(message: impl Into<String>) -> Self {
Self::Quic(message.into())
}
}