Skip to main content

modkit_auth/oauth2/
error.rs

1use thiserror::Error;
2
3/// Errors returned by the outbound `OAuth2` client credentials flow.
4///
5/// All variants are deliberately constructed so that secret values
6/// (`client_secret`, access tokens) can never appear in the formatted output.
7#[derive(Debug, Error)]
8#[non_exhaustive]
9pub enum TokenError {
10    /// HTTP transport or status error during token acquisition.
11    ///
12    /// The inner string is produced by
13    /// [`format_http_error`](crate::http_error::format_http_error) and never
14    /// contains secrets.
15    #[error("{0}")]
16    Http(String),
17
18    /// The token endpoint returned an unparseable or incomplete response.
19    #[error("invalid token response: {0}")]
20    InvalidResponse(String),
21
22    /// The token endpoint returned a `token_type` that is not `Bearer`.
23    #[error("unsupported token type: {0}")]
24    UnsupportedTokenType(String),
25
26    /// Configuration is invalid (e.g. both `token_endpoint` and `issuer_url`
27    /// are set, or neither is set).
28    #[error("OAuth2 config error: {0}")]
29    ConfigError(String),
30
31    /// The token watcher is not ready or has been shut down.
32    #[error("token unavailable: {0}")]
33    Unavailable(String),
34}
35
36#[cfg(test)]
37#[cfg_attr(coverage_nightly, coverage(off))]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn config_error_renders() {
43        let e = TokenError::ConfigError("both endpoints set".into());
44        assert_eq!(e.to_string(), "OAuth2 config error: both endpoints set");
45    }
46
47    #[test]
48    fn http_error_renders() {
49        let e = TokenError::Http("OAuth2 token HTTP 401 Unauthorized".into());
50        assert_eq!(e.to_string(), "OAuth2 token HTTP 401 Unauthorized");
51    }
52
53    #[test]
54    fn invalid_response_renders() {
55        let e = TokenError::InvalidResponse("missing access_token".into());
56        assert_eq!(
57            e.to_string(),
58            "invalid token response: missing access_token"
59        );
60    }
61
62    #[test]
63    fn unsupported_token_type_renders() {
64        let e = TokenError::UnsupportedTokenType("mac".into());
65        assert_eq!(e.to_string(), "unsupported token type: mac");
66    }
67
68    #[test]
69    fn unavailable_renders() {
70        let e = TokenError::Unavailable("watcher shut down".into());
71        assert_eq!(e.to_string(), "token unavailable: watcher shut down");
72    }
73}