use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum OAuthError {
#[error("jwks fetch failed: {0}")]
JwksFetch(String),
#[error("invalid bearer token format")]
BadBearer,
#[error("token validation failed")]
Validation(#[source] jsonwebtoken::errors::Error),
#[error("method not authorized for principal")]
ScopeDenied,
#[error("missing required configuration: {0}")]
Misconfigured(String),
#[error("introspection failed: {0}")]
IntrospectionFailed(String),
#[error("discovery failed: {0}")]
DiscoveryFailed(String),
#[error("oauth internal error: {message}")]
Internal {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},
}
#[cfg(test)]
mod tests {
use super::*;
use std::error::Error as StdError;
#[test]
fn internal_preserves_source_chain() {
let inner = std::io::Error::other("tls backend missing");
let e = OAuthError::Internal {
message: "failed to build OAuth HTTP client".into(),
source: Box::new(inner),
};
assert_eq!(
e.to_string(),
"oauth internal error: failed to build OAuth HTTP client"
);
let src = e.source().expect("source must be preserved");
assert_eq!(src.to_string(), "tls backend missing");
}
}