1use crate::{InternalError, access::AccessError, dto::prelude::*};
2use std::fmt::{self, Display};
3
4#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
11pub struct Error {
12 pub code: ErrorCode,
13 pub message: String,
14}
15
16impl Error {
17 #[must_use]
18 pub const fn new(code: ErrorCode, message: String) -> Self {
19 Self { code, message }
20 }
21
22 pub fn conflict(message: impl Into<String>) -> Self {
24 Self::new(ErrorCode::Conflict, message.into())
25 }
26
27 pub fn policy(code: ErrorCode, message: impl Into<String>) -> Self {
29 Self::new(code, message.into())
30 }
31
32 pub fn forbidden(message: impl Into<String>) -> Self {
34 Self::new(ErrorCode::Forbidden, message.into())
35 }
36
37 pub fn internal(message: impl Into<String>) -> Self {
39 Self::new(ErrorCode::Internal, message.into())
40 }
41
42 pub fn invalid(message: impl Into<String>) -> Self {
44 Self::new(ErrorCode::InvalidInput, message.into())
45 }
46
47 #[must_use]
49 pub fn operation_id_required() -> Self {
50 Self::new(
51 ErrorCode::OperationIdRequired,
52 "operation_id is required for this command".to_string(),
53 )
54 }
55
56 pub fn invariant(message: impl Into<String>) -> Self {
58 Self::new(ErrorCode::InvariantViolation, message.into())
59 }
60
61 pub fn exhausted(message: impl Into<String>) -> Self {
63 Self::new(ErrorCode::ResourceExhausted, message.into())
64 }
65
66 pub fn not_found(message: impl Into<String>) -> Self {
68 Self::new(ErrorCode::NotFound, message.into())
69 }
70
71 pub fn unauthorized(message: impl Into<String>) -> Self {
73 Self::new(ErrorCode::Unauthorized, message.into())
74 }
75
76 pub fn unavailable(message: impl Into<String>) -> Self {
78 Self::new(ErrorCode::Unavailable, message.into())
79 }
80
81 #[must_use]
83 pub fn root_data_certificate_unavailable() -> Self {
84 Self::new(
85 ErrorCode::RootDataCertificateUnavailable,
86 "root data certificate unavailable for delegation proof retrieval".to_string(),
87 )
88 }
89}
90
91impl Display for Error {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(f, "[{:?}] {}", self.code, self.message)
94 }
95}
96
97impl From<AccessError> for Error {
98 fn from(err: AccessError) -> Self {
99 Self::from(InternalError::from(err))
100 }
101}
102
103#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
110#[non_exhaustive]
111#[remain::sorted]
112pub enum ErrorCode {
113 AuthMaterialStale,
114 AuthProofExpired,
115 Conflict,
116 Forbidden,
117 Internal,
118 InternalRpcMalformed,
119 InvalidInput,
120 InvariantViolation,
121 NotFound,
122 OperationIdRequired,
123 PolicyInstanceRequiresSingletonWithDirectory,
124 PolicyReplicaRequiresSingletonWithScaling,
125 PolicyRoleAlreadyRegistered,
126 PolicyShardRequiresSingletonWithSharding,
127 PolicySingletonAlreadyRegisteredUnderParent,
128 ResourceExhausted,
129 RootDataCertificateUnavailable,
130 Unauthorized,
131 Unavailable,
132}