1use sui_id_shared::errors::ApiErrorCode;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum CoreError {
11 #[error("invalid credentials")]
12 InvalidCredentials,
13
14 #[error("authentication required")]
15 Unauthenticated,
16
17 #[error("forbidden")]
18 Forbidden,
19
20 #[error("resource not found")]
21 NotFound,
22
23 #[error("conflict: {0}")]
24 Conflict(String),
25
26 #[error("invalid request: {0}")]
27 BadRequest(String),
28
29 #[error("system not yet initialized")]
30 NotInitialized,
31
32 #[error("system already initialized")]
33 AlreadyInitialized,
34
35 #[error("OAuth/OIDC protocol error: {code}")]
36 Protocol {
37 code: ProtocolError,
38 description: String,
39 },
40
41 #[error(transparent)]
42 Store(#[from] sui_id_store::StoreError),
43
44 #[error("password hashing failure")]
45 Password,
46
47 #[error("JWT processing failure")]
48 Jwt,
49
50 #[error("internal failure")]
51 Internal,
52
53 #[error("configuration error: {0}")]
56 ConfigError(String),
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum ProtocolError {
62 InvalidRequest,
63 InvalidClient,
64 InvalidGrant,
65 UnauthorizedClient,
66 UnsupportedGrantType,
67 InvalidScope,
68 UnsupportedResponseType,
69 AccessDenied,
70 ServerError,
71 TemporarilyUnavailable,
74}
75
76impl ProtocolError {
77 pub const fn as_str(self) -> &'static str {
78 match self {
79 Self::InvalidRequest => "invalid_request",
80 Self::InvalidClient => "invalid_client",
81 Self::InvalidGrant => "invalid_grant",
82 Self::UnauthorizedClient => "unauthorized_client",
83 Self::UnsupportedGrantType => "unsupported_grant_type",
84 Self::InvalidScope => "invalid_scope",
85 Self::UnsupportedResponseType => "unsupported_response_type",
86 Self::AccessDenied => "access_denied",
87 Self::ServerError => "server_error",
88 Self::TemporarilyUnavailable => "temporarily_unavailable",
89 }
90 }
91}
92
93impl std::fmt::Display for ProtocolError {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 f.write_str(self.as_str())
96 }
97}
98
99impl CoreError {
100 pub fn api_code(&self) -> ApiErrorCode {
102 match self {
103 Self::InvalidCredentials | Self::Unauthenticated => ApiErrorCode::Unauthorized,
104 Self::Forbidden => ApiErrorCode::Forbidden,
105 Self::NotFound => ApiErrorCode::NotFound,
106 Self::Conflict(_) => ApiErrorCode::Conflict,
107 Self::BadRequest(_) => ApiErrorCode::BadRequest,
108 Self::NotInitialized | Self::AlreadyInitialized => ApiErrorCode::InvalidState,
109 Self::Protocol { .. } => ApiErrorCode::Protocol,
110 Self::Store(sui_id_store::StoreError::NotFound) => ApiErrorCode::NotFound,
111 Self::Store(sui_id_store::StoreError::Conflict) => ApiErrorCode::Conflict,
112 Self::Store(_) | Self::Password | Self::Jwt | Self::Internal | Self::ConfigError(_) => ApiErrorCode::Internal,
113 }
114 }
115}
116
117pub type CoreResult<T> = Result<T, CoreError>;