wechat_agent_rs/
errors.rs1use snafu::Snafu;
2
3#[derive(Debug, Snafu)]
5#[snafu(visibility(pub))]
6pub enum Error {
7 #[snafu(display("HTTP error: {source}"))]
9 Http { source: reqwest::Error },
10
11 #[snafu(display("JSON error: {source}"))]
13 Json { source: serde_json::Error },
14
15 #[snafu(display("IO error: {source}"))]
17 Io { source: std::io::Error },
18
19 #[snafu(display("API error (code {code}): {message}"))]
21 Api {
22 code: i64,
24 message: String,
26 },
27
28 #[snafu(display("Session expired"))]
30 SessionExpired,
31
32 #[snafu(display("QR code expired"))]
34 QrCodeExpired,
35
36 #[snafu(display("Login failed: {reason}"))]
38 LoginFailed {
39 reason: String,
41 },
42
43 #[snafu(display("No account found"))]
45 NoAccount,
46
47 #[snafu(display("Encryption error: {reason}"))]
49 Encryption {
50 reason: String,
52 },
53}
54
55pub type Result<T> = std::result::Result<T, Error>;
57
58#[cfg(test)]
59mod tests {
60 use snafu::IntoError;
61
62 use super::*;
63
64 #[test]
65 fn test_error_display_api() {
66 let err = ApiSnafu {
67 code: 42_i64,
68 message: "bad request".to_string(),
69 }
70 .build();
71 let display = format!("{err}");
72 assert!(
73 display.contains("42"),
74 "should contain error code, got: {display}"
75 );
76 assert!(
77 display.contains("bad request"),
78 "should contain message, got: {display}"
79 );
80 }
81
82 #[test]
83 fn test_error_display_login_failed() {
84 let err = LoginFailedSnafu {
85 reason: "invalid credentials".to_string(),
86 }
87 .build();
88 let display = format!("{err}");
89 assert!(
90 display.contains("invalid credentials"),
91 "should contain reason, got: {display}"
92 );
93 }
94
95 #[test]
96 fn test_error_display_encryption() {
97 let err = EncryptionSnafu {
98 reason: "bad key".to_string(),
99 }
100 .build();
101 let display = format!("{err}");
102 assert!(
103 display.contains("bad key"),
104 "should contain reason, got: {display}"
105 );
106 }
107
108 #[test]
109 fn test_error_from_io() {
110 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file missing");
111 let err: Error = IoSnafu.into_error(io_err);
112 assert!(
113 matches!(err, Error::Io { .. }),
114 "expected Io variant, got: {err:?}"
115 );
116 let display = format!("{err}");
117 assert!(
118 display.contains("file missing"),
119 "should contain source message, got: {display}"
120 );
121 }
122
123 #[test]
124 fn test_error_from_json() {
125 let json_err = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
126 let err: Error = JsonSnafu.into_error(json_err);
127 assert!(
128 matches!(err, Error::Json { .. }),
129 "expected Json variant, got: {err:?}"
130 );
131 }
132}