Skip to main content

systemprompt_oauth/
error.rs

1//! Typed error taxonomy for the systemprompt-oauth domain.
2//!
3//! Variants enumerate the security-meaningful failure modes encountered
4//! throughout the OAuth 2.0 / OIDC, `WebAuthn` and CIMD subsystems. Concrete
5//! `#[from]` adapters route `sqlx`, `std::io`, `url`, `serde_json`, and
6//! `webauthn`/`bcrypt`/`jsonwebtoken` errors into the appropriate variant
7//! so callers can match on a single `OauthError` enum.
8
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12pub enum OauthError {
13    #[error("provider error: {0}")]
14    Provider(String),
15
16    #[error("token error: {0}")]
17    Token(String),
18
19    #[error("token not found: {0}")]
20    TokenNotFound(String),
21
22    #[error("authorization code not found: {0}")]
23    CodeNotFound(String),
24
25    #[error("expired: {0}")]
26    Expired(String),
27
28    #[error("PKCE challenge mismatch: {0}")]
29    PkceMismatch(String),
30
31    #[error("invalid grant: {0}")]
32    InvalidGrant(String),
33
34    #[error("invalid client: {0}")]
35    InvalidClient(String),
36
37    #[error("client not found: {0}")]
38    ClientNotFound(String),
39
40    #[error("session error: {0}")]
41    Session(String),
42
43    #[error("webauthn error: {0}")]
44    WebAuthn(String),
45
46    #[error("user error: {0}")]
47    User(String),
48
49    #[error("repository error: {0}")]
50    Repository(#[from] sqlx::Error),
51
52    #[error("database repository error: {0}")]
53    DatabaseRepository(#[from] systemprompt_database::RepositoryError),
54
55    #[error("validation error: {0}")]
56    Validation(String),
57
58    #[error("unauthorized: {0}")]
59    Unauthorized(String),
60
61    #[error("config error: {0}")]
62    Config(String),
63
64    #[error("crypto error: {0}")]
65    Crypto(String),
66
67    #[error("internal: {0}")]
68    Internal(String),
69}
70
71pub type OauthResult<T> = Result<T, OauthError>;
72
73impl From<webauthn_rs::prelude::WebauthnError> for OauthError {
74    fn from(err: webauthn_rs::prelude::WebauthnError) -> Self {
75        Self::WebAuthn(err.to_string())
76    }
77}
78
79impl From<bcrypt::BcryptError> for OauthError {
80    fn from(err: bcrypt::BcryptError) -> Self {
81        Self::Crypto(err.to_string())
82    }
83}
84
85impl From<jsonwebtoken::errors::Error> for OauthError {
86    fn from(err: jsonwebtoken::errors::Error) -> Self {
87        Self::Token(err.to_string())
88    }
89}
90
91impl From<serde_json::Error> for OauthError {
92    fn from(err: serde_json::Error) -> Self {
93        Self::Validation(format!("json parse: {err}"))
94    }
95}
96
97impl From<systemprompt_models::errors::ConfigError> for OauthError {
98    fn from(err: systemprompt_models::errors::ConfigError) -> Self {
99        Self::Config(err.to_string())
100    }
101}
102
103impl From<systemprompt_config::SecretsBootstrapError> for OauthError {
104    fn from(err: systemprompt_config::SecretsBootstrapError) -> Self {
105        Self::Config(err.to_string())
106    }
107}