Skip to main content

htb_cli/
error.rs

1use std::fmt;
2
3#[derive(Debug, thiserror::Error)]
4pub enum HtbError {
5    #[error("Not authenticated. Run `htb auth login` first.")]
6    NotAuthenticated,
7
8    #[error("API error ({status}): {message}")]
9    Api { status: u16, message: String },
10
11    #[error("Rate limited. Try again shortly.")]
12    RateLimited,
13
14    #[error("{0}")]
15    Http(#[from] reqwest::Error),
16
17    #[error("{0}")]
18    Io(#[from] std::io::Error),
19
20    #[error("{0}")]
21    Json(#[from] serde_json::Error),
22
23    #[error("Config error: {0}")]
24    Config(String),
25}
26
27#[derive(Debug, serde::Deserialize)]
28pub struct ApiErrorBody {
29    pub message: String,
30}
31
32impl fmt::Display for ApiErrorBody {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        write!(f, "{}", self.message)
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn not_authenticated_display() {
44        let err = HtbError::NotAuthenticated;
45        assert_eq!(
46            err.to_string(),
47            "Not authenticated. Run `htb auth login` first."
48        );
49    }
50
51    #[test]
52    fn api_error_display() {
53        let err = HtbError::Api {
54            status: 403,
55            message: "Incorrect flag".into(),
56        };
57        assert_eq!(err.to_string(), "API error (403): Incorrect flag");
58    }
59}