poirebot_licorice/
errors.rs1use reqwest::{Response, StatusCode};
4use serde::Deserialize;
5use thiserror::Error;
6
7#[derive(Debug, Error)]
8pub enum LichessError {
10 #[error("exceeded request limit")]
12 RateLimited(Option<usize>),
13 #[error("request error: {0}")]
15 Request(#[from] reqwest::Error),
16 #[error("status code {0}: {1}")]
18 StatusCode(u16, String),
19 #[error("lichess error: {0}")]
21 API(#[from] APIError),
22 #[error("json parse error: {0}")]
24 ParseJSON(#[from] serde_json::Error),
25 #[error("input/output error: {0}")]
27 IO(#[from] std::io::Error),
28}
29
30impl LichessError {
31 pub(crate) async fn from_response(response: Response) -> Self {
32 match response.status() {
33 StatusCode::TOO_MANY_REQUESTS => Self::RateLimited(
34 response
35 .headers()
36 .get(reqwest::header::RETRY_AFTER)
37 .and_then(|header| header.to_str().ok())
38 .and_then(|duration| duration.parse().ok()),
39 ),
40 status => response
41 .json::<APIError>()
42 .await
43 .map(Into::into)
44 .unwrap_or_else(|_| status.into()),
45 }
46 }
47}
48
49impl From<StatusCode> for LichessError {
50 fn from(code: StatusCode) -> Self {
51 Self::StatusCode(
52 code.as_u16(),
53 code.canonical_reason().unwrap_or("unknown").to_string(),
54 )
55 }
56}
57
58#[derive(Debug, Error, Deserialize)]
60#[error("error: {error}")]
61pub struct APIError {
62 error: String,
63}