1use thiserror::Error;
2
3pub type AuthResult<T> = Result<T, AuthError>;
5
6#[derive(Error, Debug, Clone)]
8pub enum AuthError {
9 #[error("Invalid token: {message}")]
10 InvalidToken {
11 message: String,
12 provider: Option<String>,
13 },
14
15 #[error("Token expired")]
16 TokenExpired { provider: Option<String> },
17
18 #[error("Provider not configured: {provider}")]
19 ProviderNotConfigured { provider: String },
20
21 #[error("Network error: {message}")]
22 NetworkError {
23 message: String,
24 provider: Option<String>,
25 },
26
27 #[error("Configuration error: {message}")]
28 ConfigurationError { message: String },
29
30 #[error("JWT decode error: {message}")]
31 JwtError {
32 message: String,
33 provider: Option<String>,
34 },
35
36 #[error("Authentication required")]
37 AuthenticationRequired,
38
39 #[error("Authorization failed: {0}")]
40 AuthorizationError(String),
41
42 #[error("Insufficient permissions: {0}")]
43 InsufficientPermissions(String),
44
45 #[error("User not found: {0}")]
46 UserNotFound(String),
47
48 #[error("Provider error: {0}")]
49 ProviderError(String),
50
51 #[error("Unsupported operation: {0}")]
52 UnsupportedOperation(String),
53
54 #[error("Internal error: {0}")]
55 InternalError(String),
56
57 #[error("Unknown error: {message}")]
58 Unknown {
59 message: String,
60 provider: Option<String>,
61 },
62}
63
64impl AuthError {
65 pub fn provider(&self) -> Option<&str> {
67 match self {
68 AuthError::InvalidToken { provider, .. } => provider.as_deref(),
69 AuthError::TokenExpired { provider } => provider.as_deref(),
70 AuthError::NetworkError { provider, .. } => provider.as_deref(),
71 AuthError::JwtError { provider, .. } => provider.as_deref(),
72 AuthError::Unknown { provider, .. } => provider.as_deref(),
73 _ => None,
74 }
75 }
76
77 pub fn with_provider(mut self, provider: impl Into<String>) -> Self {
79 match &mut self {
80 AuthError::InvalidToken { provider: p, .. } => *p = Some(provider.into()),
81 AuthError::TokenExpired { provider: p } => *p = Some(provider.into()),
82 AuthError::NetworkError { provider: p, .. } => *p = Some(provider.into()),
83 AuthError::JwtError { provider: p, .. } => *p = Some(provider.into()),
84 AuthError::Unknown { provider: p, .. } => *p = Some(provider.into()),
85 _ => {}
86 }
87 self
88 }
89}
90
91#[cfg(feature = "authentication")]
93impl From<reqwest::Error> for AuthError {
94 fn from(err: reqwest::Error) -> Self {
95 AuthError::NetworkError {
96 message: err.to_string(),
97 provider: None,
98 }
99 }
100}
101
102#[cfg(feature = "authentication")]
103impl From<jsonwebtoken::errors::Error> for AuthError {
104 fn from(err: jsonwebtoken::errors::Error) -> Self {
105 AuthError::JwtError {
106 message: err.to_string(),
107 provider: None,
108 }
109 }
110}
111
112impl From<serde_json::Error> for AuthError {
113 fn from(err: serde_json::Error) -> Self {
114 AuthError::Unknown {
115 message: format!("JSON error: {}", err),
116 provider: None,
117 }
118 }
119}