codealong_github/
error.rs

1use codealong;
2use git2;
3use reqwest;
4
5error_chain! {
6    errors {
7        RateLimitted {}
8        Unknown {}
9    }
10
11    foreign_links {
12        Git2(git2::Error);
13        IO(std::io::Error);
14        Reqwest(reqwest::Error);
15    }
16
17    links {
18        Core(codealong::Error, codealong::ErrorKind);
19    }
20}
21
22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct ErrorPayload {
24    pub message: String,
25    pub documentation_url: Option<String>,
26}
27
28const MAX_RETRY: u64 = 4;
29const RETRY_INTERVAL_SECONDS: u64 = 60;
30
31pub fn retry_when_rate_limited(
32    f: &mut FnMut() -> Result<reqwest::Response>,
33    mut cb: Option<&mut FnMut(u64)>,
34) -> Result<reqwest::Response> {
35    for _ in 0..MAX_RETRY {
36        match f() {
37            Err(Error(ErrorKind::RateLimitted, _)) => {
38                if let Some(ref mut cb) = cb {
39                    cb(RETRY_INTERVAL_SECONDS);
40                }
41                std::thread::sleep(std::time::Duration::new(RETRY_INTERVAL_SECONDS, 0));
42            }
43            r => return r,
44        }
45    }
46    Err(ErrorKind::RateLimitted.into())
47}