Skip to main content

ccobalt/model/
error.rs

1use serde::Deserialize;
2use std::fmt;
3
4#[derive(Debug, Deserialize)]
5pub struct CobaltError {
6    pub code: String,
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub context: Option<ErrorContext>,
9}
10
11#[derive(Debug, Deserialize)]
12pub struct ErrorContext {
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub service: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub limit: Option<u32>,
17}
18
19impl fmt::Display for CobaltError {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        match self.code.to_ascii_lowercase().as_str() {
22            "error.api.unreachable" => f.write_str("API unreachable (try again later)"),
23            "error.api.timed_out" => f.write_str("API timeout (try again later)"),
24            "error.api.rate_exceeded" => f.write_str("Rate limited (try again later)"),
25            "error.api.capacity" => f.write_str("API busy (try again later)"),
26            "error.api.generic" => f.write_str("General API error (try again later)"),
27            "error.api.unknown_response" => f.write_str("Download failure. Make sure the link is valid. (unknown response)"),
28            "error.api.service.unsupported" => f.write_str("That service or website is not supported."),
29            "error.api.service.disabled" => f.write_str("Downloading from that service or website is temporarily disabled."),
30            "error.api.link.invalid" => f.write_str("That link is invalid. Make sure it is correct."),
31            "error.api.link.unsupported" => f.write_str("That link or format is unsupported."),
32            "error.api.fetch.fail" => f.write_str("Failed to fetch the media. Make sure the link is valid, or try again later."),
33            "error.api.fetch.critical" => f.write_str("Critical error fetching the media. Make sure the link is valid, or try again later."),
34            "error.api.fetch.empty" => f.write_str("The service or website returned no data. This may be caused by the site blocking the downloader (try again later)"),
35            "error.api.fetch.rate" => f.write_str("The service or website has rate limited the downloader (try again later)"),
36            "error.api.fetch.short_link" => f.write_str("Unable to resolve the shortlink. Try using the full link to the media."),
37            "error.api.content.too_long" => f.write_str("The requested content is too big."),
38            "error.api.content.video.unavailable" => f.write_str("That video is unavailable. Make sure it is not region or age restricted, and is not private."),
39            "error.api.content.video.live" => f.write_str("Live videos are unsupported."),
40            "error.api.content.video.private" => f.write_str("That video is private."),
41            "error.api.content.video.age" => f.write_str("That video is age restricted."),
42            "error.api.content.video.region" => f.write_str("That video is region restricted."),
43            "error.api.content.post.unavailable" => f.write_str("That post is unavailable. Make sure it is not region or age restricted, and is not private."),
44            "error.api.content.post.private" => f.write_str("That post is private."),
45            "error.api.content.post.age" => f.write_str("That post is age restricted."),
46            "error.api.youtube.codec" => f.write_str("Missing YouTube codec. This is a bug."),
47            "error.api.youtube.decipher" => f.write_str("Cannot decipher that video. Something probably broke."),
48            "error.api.youtube.login" => f.write_str("That video requires a logged in account, which we do not have."),
49            "error.api.youtube.token_expired" => f.write_str("Our YouTube token expired (try again later)"),
50            "error.api.youtube.temporary_disabled" => f.write_str("YouTube support is temporarily disabled. Try again later."),
51            _ => f.write_str(&self.code),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_error_display() {
62        let error = CobaltError {
63            code: "error.api.unreachable".to_string(),
64            context: None,
65        };
66        assert_eq!(format!("{}", error), "API unreachable (try again later)");
67    }
68
69    #[test]
70    fn test_error_unknown() {
71        let error = CobaltError {
72            code: "error.api.unknown".to_string(),
73            context: None,
74        };
75        assert_eq!(format!("{}", error), "error.api.unknown");
76    }
77}