#[derive(Debug, thiserror::Error)]
pub enum WebVHError {
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("not authenticated — call authenticate() first")]
NotAuthenticated,
#[error("server error ({status}): {message}")]
Server { status: u16, message: String },
#[error("DIDComm error: {0}")]
DIDComm(String),
#[error("resolver error: {0}")]
Resolver(String),
#[error("trust task refused ({code}): {message}")]
Refused { code: String, message: String },
#[error("trust task transport error: {0}")]
Transport(String),
}
pub type Result<T> = std::result::Result<T, WebVHError>;
impl WebVHError {
pub fn kind(&self) -> &'static str {
match self {
Self::Http(_) => "http",
Self::Json(_) => "json",
Self::NotAuthenticated => "not_authenticated",
Self::Server { .. } => "server",
Self::DIDComm(_) => "didcomm",
Self::Resolver(_) => "resolver",
Self::Refused { .. } => "refused",
Self::Transport(_) => "transport",
}
}
}
#[cfg(feature = "server-core")]
pub(crate) fn redact_server_message(raw: &str) -> String {
const MAX_LEN: usize = 200;
let despaced: String = raw
.chars()
.map(|c| if c.is_control() { ' ' } else { c })
.collect();
let normalized = despaced.split_whitespace().collect::<Vec<_>>().join(" ");
if normalized.is_empty() {
return "unspecified server error".to_string();
}
if normalized.chars().count() <= MAX_LEN {
return normalized;
}
let mut capped: String = normalized.chars().take(MAX_LEN - 1).collect();
capped.push('\u{2026}');
capped
}
#[cfg(test)]
mod tests {
#[cfg(feature = "server-core")]
use super::*;
#[cfg(feature = "server-core")]
#[test]
fn redact_server_message_bounds_and_sanitizes() {
assert_eq!(redact_server_message("bad request"), "bad request");
let raw = format!("line1{}line2", char::from(10u8));
assert_eq!(redact_server_message(&raw), "line1 line2");
let long = redact_server_message(&"x".repeat(500));
assert_eq!(long.chars().count(), 200);
assert!(
long.ends_with('\u{2026}'),
"truncated message must be marked"
);
let exact = redact_server_message(&"y".repeat(200));
assert_eq!(exact, "y".repeat(200));
assert!(redact_server_message(&"z".repeat(201)).ends_with('\u{2026}'));
assert_eq!(redact_server_message(" "), "unspecified server error");
}
}