use night_fury_core::NightFuryError;
#[derive(Debug, thiserror::Error)]
pub enum SiteError {
#[error("refresh failed on site '{site}': {reason}")]
RefreshFailed { site: &'static str, reason: String },
#[error("validation failed on site '{site}': {reason}")]
ValidationFailed { site: &'static str, reason: String },
#[error("manual login required for site '{site}' — automated login not supported")]
ManualLoginRequired { site: &'static str },
#[error("login failed: {0:?}")]
LoginFailed(AuthFailureKind),
#[error("browser error during site operation: {0}")]
Browser(#[from] NightFuryError),
}
#[derive(Debug, Clone)]
pub enum AuthFailureKind {
CookieExpired,
CredentialsRejected,
RateLimited { retry_after: std::time::Duration },
AntibotBlock { challenge_type: String },
AccountSuspended,
Other(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn site_error_displays_with_site_id() {
let err = SiteError::RefreshFailed {
site: "twitter",
reason: "auth_token missing".into(),
};
let msg = err.to_string();
assert!(msg.contains("twitter"));
assert!(msg.contains("auth_token missing"));
}
#[test]
fn auth_failure_kind_debug() {
let kind = AuthFailureKind::RateLimited {
retry_after: std::time::Duration::from_secs(60),
};
let debug = format!("{kind:?}");
assert!(debug.contains("RateLimited"));
}
#[test]
fn auth_failure_kind_variants_exist() {
let _ = AuthFailureKind::CookieExpired;
let _ = AuthFailureKind::CredentialsRejected;
let _ = AuthFailureKind::AccountSuspended;
let _ = AuthFailureKind::AntibotBlock {
challenge_type: "captcha".into(),
};
let _ = AuthFailureKind::Other("custom".into());
}
}