1#[derive(thiserror::Error, Debug)]
2pub enum Error {
3 #[error("email address not set")]
4 ConfigMissingEmail,
5
6 #[error("failed to create block mode decryptor")]
7 CreateBlockMode { source: aes::cipher::InvalidLength },
8
9 #[error("failed to create block mode decryptor")]
10 CreateHmac { source: aes::cipher::InvalidLength },
11
12 #[error("failed to create directory at {}", .file.display())]
13 CreateDirectory {
14 source: std::io::Error,
15 file: std::path::PathBuf,
16 },
17
18 #[error("failed to create reqwest client")]
19 CreateReqwestClient { source: reqwest::Error },
20
21 #[error("failed to create sso callback server: {err}")]
22 CreateSSOCallbackServer { err: std::io::Error },
23
24 #[error("failed to decrypt: {msg}")]
25 Decrypt { msg: String },
26
27 #[error("failed to find free port in {range}")]
28 FailedToFindFreePort { range: String },
29
30 #[error("failed to parse pinentry output ({out:?})")]
31 FailedToParsePinentry { out: String },
32
33 #[error("failed to process sso callback ({msg})")]
34 FailedToProcessSSOCallback { msg: String },
35
36 #[error("failed to open web browser: {err}")]
37 FailedToOpenWebBrowser { err: std::io::Error },
38
39 #[error("failed to read from stdin: {err}")]
40 FailedToReadFromStdin { err: std::io::Error },
41
42 #[error(
43 "failed to run editor {}: {err}",
44 .editor.to_string_lossy(),
45 )]
46 FailedToFindEditor {
47 editor: std::path::PathBuf,
48 err: std::io::Error,
49 },
50
51 #[error(
52 "failed to run editor {} {}: {res:?}",
53 .editor.to_string_lossy(),
54 .args.iter().map(|s| s.to_string_lossy()).collect::<Vec<_>>().join(" ")
55 )]
56 FailedToRunEditor {
57 editor: std::path::PathBuf,
58 args: Vec<std::ffi::OsString>,
59 res: std::process::ExitStatus,
60 },
61
62 #[error("failed to expand with hkdf")]
63 HkdfExpand,
64
65 #[error("incorrect api key")]
66 IncorrectApiKey,
67
68 #[error("{message}")]
69 IncorrectPassword { message: String },
70
71 #[error("invalid base64")]
72 InvalidBase64 { source: base64::DecodeError },
73
74 #[error("invalid cipherstring: {reason}")]
75 InvalidCipherString { reason: String },
76
77 #[error(
78 "invalid value for ${var}: {}",
79 .editor.to_string_lossy()
80 )]
81 InvalidEditor {
82 var: String,
83 editor: std::ffi::OsString,
84 },
85
86 #[error("invalid mac")]
87 InvalidMac,
88
89 #[error("invalid two factor provider type: {ty}")]
90 InvalidTwoFactorProvider { ty: String },
91
92 #[error("failed to parse JSON")]
93 Json { source: serde_json::Error },
94
95 #[error("failed to load config from {}", .file.display())]
96 LoadConfig {
97 source: std::io::Error,
98 file: std::path::PathBuf,
99 },
100
101 #[error("failed to load config from {}", .file.display())]
102 LoadConfigAsync {
103 source: tokio::io::Error,
104 file: std::path::PathBuf,
105 },
106
107 #[error("failed to load config from {}", .file.display())]
108 LoadConfigJson {
109 source: serde_json::Error,
110 file: std::path::PathBuf,
111 },
112
113 #[error("failed to load db from {}", .file.display())]
114 LoadDb {
115 source: std::io::Error,
116 file: std::path::PathBuf,
117 },
118
119 #[error("failed to load db from {}", .file.display())]
120 LoadDbAsync {
121 source: tokio::io::Error,
122 file: std::path::PathBuf,
123 },
124
125 #[error("failed to load db from {}", .file.display())]
126 LoadDbJson {
127 source: serde_json::Error,
128 file: std::path::PathBuf,
129 },
130
131 #[error("failed to load device id from {}", .file.display())]
132 LoadDeviceId {
133 source: tokio::io::Error,
134 file: std::path::PathBuf,
135 },
136
137 #[error("failed to load client cert from {}", .file.display())]
138 LoadClientCert {
139 source: tokio::io::Error,
140 file: std::path::PathBuf,
141 },
142
143 #[error("invalid padding")]
144 Padding,
145
146 #[error("failed to parse match type {s}")]
147 ParseMatchType { s: String },
148
149 #[error("pbkdf2 requires at least 1 iteration (got 0)")]
150 Pbkdf2ZeroIterations,
151
152 #[error("failed to run pbkdf2")]
153 Pbkdf2,
154
155 #[error("failed to run argon2")]
156 Argon2,
157
158 #[error("pinentry cancelled")]
159 PinentryCancelled,
160
161 #[error("native password prompt unavailable on this platform")]
162 NativePromptUnsupported,
163
164 #[error("native password prompt failed at {stage}: code {code}")]
165 NativePromptFailed { code: i32, stage: &'static str },
166
167 #[error("pinentry error: {error}")]
168 PinentryErrorMessage { error: String },
169
170 #[error("error reading pinentry output")]
171 PinentryReadOutput { source: tokio::io::Error },
172
173 #[error("error waiting for pinentry to exit")]
174 PinentryWait { source: tokio::io::Error },
175
176 #[error("This device has not yet been registered with the Bitwarden server. Run `bwx register` first, and then try again.")]
177 RegistrationRequired,
178
179 #[error("failed to remove db at {}", .file.display())]
180 RemoveDb {
181 source: std::io::Error,
182 file: std::path::PathBuf,
183 },
184
185 #[error("api request returned error: {status}")]
186 RequestFailed { status: u16 },
187
188 #[error("api request unauthorized")]
189 RequestUnauthorized,
190
191 #[error("error making api request")]
192 Reqwest { source: reqwest::Error },
193
194 #[error("failed to decrypt")]
195 Rsa { source: rsa::errors::Error },
196
197 #[error("failed to decrypt")]
198 RsaPkcs8 { source: rsa::pkcs8::Error },
199
200 #[error("failed to save config to {}", .file.display())]
201 SaveConfig {
202 source: std::io::Error,
203 file: std::path::PathBuf,
204 },
205
206 #[error("failed to save config to {}", .file.display())]
207 SaveConfigJson {
208 source: serde_json::Error,
209 file: std::path::PathBuf,
210 },
211
212 #[error("failed to save db to {}", .file.display())]
213 SaveDb {
214 source: std::io::Error,
215 file: std::path::PathBuf,
216 },
217
218 #[error("failed to save db to {}", .file.display())]
219 SaveDbAsync {
220 source: tokio::io::Error,
221 file: std::path::PathBuf,
222 },
223
224 #[error("failed to save db to {}", .file.display())]
225 SaveDbJson {
226 source: serde_json::Error,
227 file: std::path::PathBuf,
228 },
229
230 #[error("error spawning pinentry")]
231 Spawn { source: tokio::io::Error },
232
233 #[error("cipherstring type {ty} too old\n\nPlease rotate your account encryption key (https://bitwarden.com/help/article/account-encryption-key/) and try again.")]
234 TooOldCipherStringType { ty: String },
235
236 #[error("two factor required")]
237 TwoFactorRequired {
238 providers: Vec<crate::api::TwoFactorProviderType>,
239 sso_email_2fa_session_token: Option<String>,
240 },
241
242 #[error("unimplemented cipherstring type: {ty}")]
243 UnimplementedCipherStringType { ty: String },
244
245 #[error("error writing to pinentry stdin")]
246 WriteStdin { source: tokio::io::Error },
247
248 #[error("invalid kdf type: {ty}")]
249 InvalidKdfType { ty: String },
250
251 #[error("{msg}")]
252 Totp { msg: String },
253}
254
255pub type Result<T> = std::result::Result<T, Error>;