xjp_oidc/
errors.rs

1//! Error types for xjp-oidc SDK
2
3use thiserror::Error;
4
5/// Main error type for the xjp-oidc SDK
6#[derive(Error, Debug)]
7pub enum Error {
8    /// Network-related errors
9    #[error("network error: {0}")]
10    Network(String),
11
12    /// Discovery endpoint errors
13    #[error("discovery error: {0}")]
14    Discovery(String),
15
16    /// JWKS endpoint errors  
17    #[error("jwks error: {0}")]
18    Jwks(String),
19
20    /// Token verification failures
21    #[error("verification failed: {0}")]
22    Verification(String),
23
24    /// OAuth/OIDC protocol errors from the server
25    #[error("oauth error: {error} - {description:?}")]
26    OAuth {
27        /// Error code as per RFC 6749
28        error: String,
29        /// Human-readable error description
30        description: Option<String>,
31    },
32
33    /// Invalid parameter provided to a function
34    #[error("invalid parameter: {0}")]
35    InvalidParam(&'static str),
36
37    /// Attempt to use server-only function in browser/WASM environment
38    #[error("server-only function called in browser")]
39    ServerOnly,
40
41    /// Recent login required (step-up authentication needed)
42    #[error("recent login required")]
43    RequireRecentLogin,
44
45    /// Operation timed out
46    #[error("timeout")]
47    Timeout,
48
49    /// HTTP client errors
50    #[error("http client error: {0}")]
51    HttpClient(#[from] crate::http::HttpClientError),
52
53    /// JSON parsing errors
54    #[error("json error: {0}")]
55    Json(#[from] serde_json::Error),
56
57    /// URL parsing errors
58    #[error("url parse error: {0}")]
59    UrlParse(#[from] url::ParseError),
60
61    /// Base64 decoding errors
62    #[error("base64 decode error: {0}")]
63    Base64(String),
64
65    /// JWT/JWS errors
66    #[error("jwt error: {0}")]
67    Jwt(String),
68
69    /// Cache-related errors
70    #[error("cache error: {0}")]
71    Cache(String),
72
73    /// Missing required configuration
74    #[error("missing configuration: {0}")]
75    MissingConfig(&'static str),
76
77    /// Invalid state during operation
78    #[error("invalid state: {0}")]
79    InvalidState(String),
80}
81
82impl Error {
83    /// Create an OAuth error from server response
84    pub fn oauth(error: impl Into<String>, description: Option<String>) -> Self {
85        Self::OAuth { error: error.into(), description }
86    }
87
88    /// Check if this is a specific OAuth error code
89    pub fn is_oauth_error(&self, code: &str) -> bool {
90        matches!(self, Self::OAuth { error, .. } if error == code)
91    }
92
93    /// Check if this error indicates that recent login is required
94    pub fn requires_recent_login(&self) -> bool {
95        matches!(self, Self::RequireRecentLogin)
96            || self.is_oauth_error("login_required")
97            || self.is_oauth_error("interaction_required")
98    }
99
100    /// Check if this error is retryable
101    pub fn is_retryable(&self) -> bool {
102        matches!(self, Self::Network(_) | Self::Timeout | Self::Discovery(_) | Self::Jwks(_))
103    }
104}
105
106/// Result type alias for operations that may fail with Error
107pub type Result<T> = std::result::Result<T, Error>;