Skip to main content

tail_fin_common/
error.rs

1use night_fury_core::NightFuryError;
2use tail_fin_core::SiteError;
3
4#[derive(Debug, thiserror::Error)]
5pub enum TailFinError {
6    #[error("not logged in: auth cookie not found")]
7    AuthRequired,
8
9    #[error("browser error: {0}")]
10    Browser(#[from] NightFuryError),
11
12    #[error("API error: {0}")]
13    Api(String),
14
15    #[error("IO error: {0}")]
16    Io(String),
17
18    #[error("parse error: {0}")]
19    Parse(String),
20
21    #[error("site error: {0}")]
22    Site(#[from] SiteError),
23}
24
25impl From<serde_json::Error> for TailFinError {
26    fn from(e: serde_json::Error) -> Self {
27        TailFinError::Parse(e.to_string())
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn serde_json_error_converts_to_parse_variant() {
37        let bad_json = "not json at all";
38        let serde_err: serde_json::Error =
39            serde_json::from_str::<serde_json::Value>(bad_json).unwrap_err();
40        let tail_err: TailFinError = serde_err.into();
41        match &tail_err {
42            TailFinError::Parse(msg) => assert!(!msg.is_empty()),
43            other => panic!("expected Parse variant, got {:?}", other),
44        }
45    }
46
47    #[test]
48    fn display_auth_required() {
49        let err = TailFinError::AuthRequired;
50        assert_eq!(err.to_string(), "not logged in: auth cookie not found");
51    }
52
53    #[test]
54    fn display_api_error() {
55        let err = TailFinError::Api("rate limited".into());
56        assert_eq!(err.to_string(), "API error: rate limited");
57    }
58
59    #[test]
60    fn display_io_error() {
61        let err = TailFinError::Io("file not found".into());
62        assert_eq!(err.to_string(), "IO error: file not found");
63    }
64
65    #[test]
66    fn display_parse_error() {
67        let err = TailFinError::Parse("unexpected token".into());
68        assert_eq!(err.to_string(), "parse error: unexpected token");
69    }
70
71    #[test]
72    fn debug_output_is_not_empty() {
73        let err = TailFinError::AuthRequired;
74        let debug = format!("{:?}", err);
75        assert!(!debug.is_empty());
76    }
77
78    #[test]
79    fn tail_fin_error_from_site_error() {
80        // SiteError now lives in tail-fin-core; TailFinError::Site has
81        // `#[from]` so conversion still works transparently.
82        let site_err = SiteError::ManualLoginRequired { site: "shopee" };
83        let tail_err: TailFinError = site_err.into();
84        match tail_err {
85            TailFinError::Site(_) => {}
86            other => panic!("expected Site variant, got {other:?}"),
87        }
88    }
89}