+89
-5
crates/jacquard/src/client/error.rs
+89
-5
crates/jacquard/src/client/error.rs
···
1
-
use jacquard_common::error::{AuthError, ClientError};
1
+
use jacquard_common::error::{AuthError, ClientError, ClientErrorKind};
2
2
use jacquard_common::types::did::Did;
3
3
use jacquard_common::types::nsid::Nsid;
4
4
use jacquard_common::types::string::{RecordKey, Rkey};
···
11
11
12
12
/// Error type for Agent convenience methods
13
13
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
14
-
#[error("{kind}")]
15
14
pub struct AgentError {
16
15
#[diagnostic_source]
17
16
kind: AgentErrorKind,
···
26
25
xrpc: Option<Data<'static>>,
27
26
}
28
27
28
+
impl std::fmt::Display for AgentError {
29
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30
+
write!(f, "{}", self.kind)?;
31
+
32
+
// Add context if available
33
+
if let Some(context) = &self.context {
34
+
write!(f, ": {}", context)?;
35
+
}
36
+
37
+
// Add URL if available
38
+
if let Some(url) = &self.url {
39
+
write!(f, " (url: {})", url)?;
40
+
}
41
+
42
+
// Add details if available
43
+
if let Some(details) = &self.details {
44
+
write!(f, " [{}]", details)?;
45
+
}
46
+
47
+
Ok(())
48
+
}
49
+
}
50
+
29
51
/// Error categories for Agent operations
30
52
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
31
53
pub enum AgentErrorKind {
32
54
/// Transport/network layer failure
33
-
#[error("client error")]
34
-
#[diagnostic(code(jacquard::agent::client))]
55
+
#[error("client error (see context for details)")]
56
+
#[diagnostic(
57
+
code(jacquard::agent::client),
58
+
help("check source error and context for specific failure details")
59
+
)]
35
60
Client,
36
61
37
62
/// No session available for operations requiring authentication
···
226
251
227
252
impl From<ClientError> for AgentError {
228
253
fn from(e: ClientError) -> Self {
229
-
Self::new(AgentErrorKind::Client, Some(Box::new(e)))
254
+
use smol_str::ToSmolStr;
255
+
256
+
let context_msg: SmolStr;
257
+
let help_msg: SmolStr;
258
+
let url = e.url().map(|s| s.to_smolstr());
259
+
let details = e.details().map(|s| s.to_smolstr());
260
+
261
+
// Build context and help based on the error kind
262
+
match e.kind() {
263
+
ClientErrorKind::Transport => {
264
+
help_msg = "check network connectivity and server availability".to_smolstr();
265
+
context_msg = "network/transport error during request".to_smolstr();
266
+
}
267
+
ClientErrorKind::InvalidRequest(msg) => {
268
+
help_msg = "verify request parameters are valid".to_smolstr();
269
+
context_msg = smol_str::format_smolstr!("invalid request: {}", msg);
270
+
}
271
+
ClientErrorKind::Encode(msg) => {
272
+
help_msg = "check request body format".to_smolstr();
273
+
context_msg = smol_str::format_smolstr!("failed to encode request: {}", msg);
274
+
}
275
+
ClientErrorKind::Decode(msg) => {
276
+
help_msg = "server returned unexpected response format".to_smolstr();
277
+
context_msg = smol_str::format_smolstr!("failed to decode response: {}", msg);
278
+
}
279
+
ClientErrorKind::Http { status } => {
280
+
help_msg = match status.as_u16() {
281
+
400..=499 => "check request parameters and authentication",
282
+
500..=599 => "server error - try again later or check server logs",
283
+
_ => "unexpected HTTP status code",
284
+
}
285
+
.to_smolstr();
286
+
context_msg = smol_str::format_smolstr!("HTTP error {}", status);
287
+
}
288
+
ClientErrorKind::Auth(auth_err) => {
289
+
help_msg = "verify authentication credentials and session".to_smolstr();
290
+
context_msg = smol_str::format_smolstr!("authentication error: {}", auth_err);
291
+
}
292
+
ClientErrorKind::IdentityResolution => {
293
+
help_msg = "check handle/DID is valid and resolvable".to_smolstr();
294
+
context_msg = "identity resolution failed".to_smolstr();
295
+
}
296
+
ClientErrorKind::Storage => {
297
+
help_msg = "verify storage backend is accessible".to_smolstr();
298
+
context_msg = "storage operation failed".to_smolstr();
299
+
}
300
+
}
301
+
302
+
let mut error = Self::new(AgentErrorKind::Client, Some(Box::new(e)));
303
+
error = error.with_context(context_msg);
304
+
error = error.with_help(help_msg);
305
+
306
+
if let Some(url) = url {
307
+
error = error.with_url(url);
308
+
}
309
+
if let Some(details) = details {
310
+
error = error.with_details(details);
311
+
}
312
+
313
+
error
230
314
}
231
315
}
232
316