1use thiserror::Error;
4use warp::http::StatusCode;
5use warp::reject::Reject;
6
7#[derive(Debug, Error)]
9pub enum WarpError {
10 #[error("Invalid message: {0}")]
12 InvalidMessage(String),
13
14 #[error("Unsupported protocol version: {0}")]
16 UnsupportedVersion(String),
17
18 #[error("Session not found: {0}")]
20 SessionNotFound(String),
21
22 #[error("Serialization error: {0}")]
24 Serialization(#[from] serde_json::Error),
25
26 #[error("Internal error: {0}")]
28 Internal(String),
29}
30
31impl Reject for WarpError {}
32
33impl WarpError {
35 #[must_use]
37 pub const fn status_code(&self) -> StatusCode {
38 match self {
39 WarpError::InvalidMessage(_) | WarpError::UnsupportedVersion(_) => {
40 StatusCode::BAD_REQUEST
41 }
42 WarpError::SessionNotFound(_) => StatusCode::NOT_FOUND,
43 WarpError::Serialization(_) | WarpError::Internal(_) => {
44 StatusCode::INTERNAL_SERVER_ERROR
45 }
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_invalid_message_error() {
56 let error = WarpError::InvalidMessage("bad json".to_string());
57 assert_eq!(error.to_string(), "Invalid message: bad json");
58 assert_eq!(error.status_code(), StatusCode::BAD_REQUEST);
59 }
60
61 #[test]
62 fn test_unsupported_version_error() {
63 let error = WarpError::UnsupportedVersion("1.0.0".to_string());
64 assert_eq!(error.to_string(), "Unsupported protocol version: 1.0.0");
65 assert_eq!(error.status_code(), StatusCode::BAD_REQUEST);
66 }
67
68 #[test]
69 fn test_session_not_found_error() {
70 let error = WarpError::SessionNotFound("abc-123".to_string());
71 assert_eq!(error.to_string(), "Session not found: abc-123");
72 assert_eq!(error.status_code(), StatusCode::NOT_FOUND);
73 }
74
75 #[test]
76 fn test_serialization_error() {
77 let json_err = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
78 let error = WarpError::Serialization(json_err);
79 assert!(error.to_string().starts_with("Serialization error:"));
80 assert_eq!(error.status_code(), StatusCode::INTERNAL_SERVER_ERROR);
81 }
82
83 #[test]
84 fn test_internal_error() {
85 let error = WarpError::Internal("something went wrong".to_string());
86 assert_eq!(error.to_string(), "Internal error: something went wrong");
87 assert_eq!(error.status_code(), StatusCode::INTERNAL_SERVER_ERROR);
88 }
89
90 #[test]
91 fn test_from_serde_json_error() {
92 let json_err = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
93 let error: WarpError = json_err.into();
94 assert!(matches!(error, WarpError::Serialization(_)));
95 }
96
97 #[test]
98 fn test_error_is_send_sync() {
99 fn assert_send_sync<T: Send + Sync>() {}
100 assert_send_sync::<WarpError>();
101 }
102
103 #[test]
104 fn test_error_debug_format() {
105 let error = WarpError::InvalidMessage("test".to_string());
106 let debug = format!("{error:?}");
107 assert!(debug.contains("InvalidMessage"));
108 assert!(debug.contains("test"));
109 }
110
111 #[test]
112 fn test_error_implements_reject() {
113 fn assert_reject<T: Reject>() {}
114 assert_reject::<WarpError>();
115 }
116}