1use crate::exit::ExitCode;
8
9#[derive(Debug, thiserror::Error)]
10pub enum ApiError {
11 #[error("transport error talking to Tracker")]
12 Transport(#[from] reqwest::Error),
13 #[error("not authenticated: the token was rejected (401)")]
14 Unauthorized,
15 #[error("forbidden (403): the account lacks rights, or the organisation header is wrong")]
16 Forbidden,
17 #[error(
21 "the Wiki refused this token: it needs the wiki:read permission — sign in again \
22 with `ytcli auth login` — or this account cannot see that page"
23 )]
24 WikiForbidden,
25 #[error(
29 "the Wiki is not set up in this organisation yet — open https://wiki.yandex.ru once, \
30 signed in to it, and try again"
31 )]
32 WikiNotEnabled,
33 #[error(
36 "the Wiki refused this write: the token needs the wiki:write permission — sign in \
37 again with `ytcli auth login` — or this account may not edit that page"
38 )]
39 WikiWriteForbidden,
40 #[error("{0} not found")]
41 NotFound(String),
42 #[error("rate limited by Tracker (429)")]
43 RateLimited,
44 #[error("Tracker rejected the request ({status}): {message}")]
45 Rejected {
46 status: reqwest::StatusCode,
47 message: String,
48 },
49 #[error("could not decode the Tracker response")]
50 Decode(#[source] serde_json::Error),
51}
52
53impl ApiError {
54 #[must_use]
55 pub fn exit_code(&self) -> ExitCode {
56 match self {
57 Self::Unauthorized | Self::WikiForbidden | Self::WikiWriteForbidden => ExitCode::Auth,
58 Self::NotFound(_) => ExitCode::NotFound,
59 Self::Forbidden | Self::WikiNotEnabled | Self::RateLimited | Self::Rejected { .. } => {
60 ExitCode::ApiRejected
61 }
62 Self::Transport(_) | Self::Decode(_) => ExitCode::Failure,
63 }
64 }
65}