use thiserror::Error;
#[derive(Debug, Error)]
pub enum ClientError {
#[error("connection failed: {0}")]
Connection(String),
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("WebSocket error: {0}")]
WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
#[error("parse error: {0}")]
Parse(String),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("SSE error: {0}")]
Sse(String),
#[error("connection closed")]
Closed,
#[error("invalid URL: {0}")]
InvalidUrl(String),
#[error("state error: {0}")]
State(String),
}
impl ClientError {
pub fn connection(msg: impl Into<String>) -> Self {
Self::Connection(msg.into())
}
pub fn parse(msg: impl Into<String>) -> Self {
Self::Parse(msg.into())
}
pub fn sse(msg: impl Into<String>) -> Self {
Self::Sse(msg.into())
}
pub fn state(msg: impl Into<String>) -> Self {
Self::State(msg.into())
}
}
pub type Result<T> = std::result::Result<T, ClientError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = ClientError::connection("refused");
assert_eq!(format!("{}", err), "connection failed: refused");
let err = ClientError::parse("invalid JSON");
assert_eq!(format!("{}", err), "parse error: invalid JSON");
let err = ClientError::Closed;
assert_eq!(format!("{}", err), "connection closed");
}
#[test]
fn test_error_constructors() {
let err = ClientError::connection("test");
assert!(matches!(err, ClientError::Connection(_)));
let err = ClientError::sse("stream ended");
assert!(matches!(err, ClientError::Sse(_)));
let err = ClientError::state("invalid patch");
assert!(matches!(err, ClientError::State(_)));
}
}