1use auths_core::error::AuthsErrorInfo;
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5#[non_exhaustive]
6pub enum FreezeError {
7 #[error(transparent)]
8 Io(#[from] std::io::Error),
9 #[error("failed to parse freeze state: {0}")]
10 Deserialization(#[from] serde_json::Error),
11 #[error("invalid duration format: {0}")]
12 InvalidDuration(String),
13 #[error("duration must be greater than zero")]
14 ZeroDuration,
15}
16
17#[derive(Debug, Error)]
18#[non_exhaustive]
19pub enum StorageError {
20 #[cfg(feature = "git-storage")]
21 #[error(transparent)]
22 Git(#[from] git2::Error),
23 #[error("serialization error: {0}")]
24 Serialization(#[from] serde_json::Error),
25 #[error("I/O error: {0}")]
26 Io(#[from] std::io::Error),
27 #[error("not found: {0}")]
28 NotFound(String),
29 #[error("{0}")]
30 InvalidData(String),
31 #[error("schema validation failed: {0}")]
32 SchemaValidation(String),
33 #[error("index error: {0}")]
34 Index(String),
35}
36
37#[derive(Debug, Error)]
38#[non_exhaustive]
39pub enum InitError {
40 #[cfg(feature = "git-storage")]
41 #[error(transparent)]
42 Git(#[from] git2::Error),
43 #[error("KERI operation failed: {0}")]
44 Keri(String),
45 #[error("key operation failed: {0}")]
46 Key(#[from] auths_core::error::AgentError),
47 #[error("{0}")]
48 InvalidData(String),
49 #[error("storage operation failed: {0}")]
50 Storage(#[from] StorageError),
51 #[error("registry error: {0}")]
52 Registry(String),
53 #[error("crypto operation failed: {0}")]
54 Crypto(String),
55 #[error("identity error: {0}")]
56 Identity(#[from] crate::identity::helpers::IdentityError),
57 #[error("witness receipting failed: {0}")]
58 Witness(String),
59}
60
61impl AuthsErrorInfo for FreezeError {
62 fn error_code(&self) -> &'static str {
63 match self {
64 Self::Io(_) => "AUTHS-E4001",
65 Self::Deserialization(_) => "AUTHS-E4002",
66 Self::InvalidDuration(_) => "AUTHS-E4003",
67 Self::ZeroDuration => "AUTHS-E4004",
68 }
69 }
70
71 fn suggestion(&self) -> Option<&'static str> {
72 match self {
73 Self::Io(_) => Some("Check file permissions and disk space"),
74 Self::Deserialization(_) => {
75 Some("The freeze state file may be corrupted; try deleting it")
76 }
77 Self::InvalidDuration(_) => {
78 Some("Use a valid duration format (e.g. '30m', '2h', '7d')")
79 }
80 Self::ZeroDuration => Some("Specify a positive duration"),
81 }
82 }
83}
84
85impl AuthsErrorInfo for StorageError {
86 fn error_code(&self) -> &'static str {
87 match self {
88 #[cfg(feature = "git-storage")]
89 Self::Git(_) => "AUTHS-E4101",
90 Self::Serialization(_) => "AUTHS-E4102",
91 Self::Io(_) => "AUTHS-E4103",
92 Self::NotFound(_) => "AUTHS-E4104",
93 Self::InvalidData(_) => "AUTHS-E4105",
94 Self::SchemaValidation(_) => "AUTHS-E4106",
95 Self::Index(_) => "AUTHS-E4107",
96 }
97 }
98
99 fn suggestion(&self) -> Option<&'static str> {
100 match self {
101 #[cfg(feature = "git-storage")]
102 Self::Git(_) => Some("Check that the Git repository is not corrupted"),
103 Self::Serialization(_) => {
104 Some("Failed to serialize storage data; this may indicate a version mismatch")
105 }
106 Self::Io(_) => Some("Check file permissions and disk space"),
107 Self::NotFound(_) => Some("Verify the identity or resource exists"),
108 Self::InvalidData(_) => Some("The stored data may be corrupted; try re-initializing"),
109 Self::SchemaValidation(_) => Some("Ensure data matches the expected schema version"),
110 Self::Index(_) => Some("Try rebuilding the index"),
111 }
112 }
113}
114
115impl AuthsErrorInfo for InitError {
116 fn error_code(&self) -> &'static str {
117 match self {
118 #[cfg(feature = "git-storage")]
119 Self::Git(_) => "AUTHS-E4201",
120 Self::Keri(_) => "AUTHS-E4202",
121 Self::Key(_) => "AUTHS-E4203",
122 Self::InvalidData(_) => "AUTHS-E4204",
123 Self::Storage(_) => "AUTHS-E4205",
124 Self::Registry(_) => "AUTHS-E4206",
125 Self::Crypto(_) => "AUTHS-E4207",
126 Self::Identity(_) => "AUTHS-E4208",
127 Self::Witness(_) => "AUTHS-E4209",
128 }
129 }
130
131 fn suggestion(&self) -> Option<&'static str> {
132 match self {
133 #[cfg(feature = "git-storage")]
134 Self::Git(_) => Some("Check that the Git repository is accessible"),
135 Self::Keri(_) => Some("KERI event processing failed; check identity state"),
136 Self::Key(_) => Some(
137 "Check keychain access and passphrase. Headless/CI (no Touch ID): set \
138 AUTHS_KEYCHAIN_BACKEND=file AUTHS_KEYCHAIN_FILE=<path> AUTHS_PASSPHRASE=<pass>, \
139 or run `auths init --profile ci`.",
140 ),
141 Self::InvalidData(_) => {
142 Some("Identity data is malformed; try re-initializing with `auths init`")
143 }
144 Self::Storage(_) => Some("Check storage backend connectivity"),
145 Self::Registry(_) => Some("Check registry backend configuration"),
146 Self::Crypto(_) => Some(
147 "A cryptographic operation during initialization failed; check your keychain access",
148 ),
149 Self::Identity(_) => {
150 Some("Identity initialization failed; check storage and keychain configuration")
151 }
152 Self::Witness(_) => Some(
153 "Too few of the identity's designated witnesses returned a valid receipt; \
154 check witness connectivity and the configured threshold",
155 ),
156 }
157 }
158}