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(
38 "the Wiki refused this write (403) without saying why: either the token lacks the \
39 wiki:write permission — sign in again with `ytcli auth login` — or this account \
40 may not edit or create pages there (`ytcli wiki access <page>` shows who may)"
41 )]
42 WikiWriteForbidden,
43 #[error("{0} not found")]
44 NotFound(String),
45 #[error("rate limited by Tracker (429)")]
46 RateLimited,
47 #[error("Tracker rejected the request ({status}): {message}")]
48 Rejected {
49 status: reqwest::StatusCode,
50 message: String,
51 },
52 #[error("the Wiki rejected the request ({status}): {message}")]
56 WikiRejected {
57 status: reqwest::StatusCode,
58 message: String,
59 },
60 #[error("could not decode the Tracker response")]
61 Decode(#[source] serde_json::Error),
62}
63
64impl ApiError {
65 #[must_use]
66 pub fn exit_code(&self) -> ExitCode {
67 match self {
68 Self::Unauthorized | Self::WikiForbidden | Self::WikiWriteForbidden => ExitCode::Auth,
69 Self::NotFound(_) => ExitCode::NotFound,
70 Self::Forbidden
71 | Self::WikiNotEnabled
72 | Self::RateLimited
73 | Self::Rejected { .. }
74 | Self::WikiRejected { .. } => ExitCode::ApiRejected,
75 Self::Transport(_) | Self::Decode(_) => ExitCode::Failure,
76 }
77 }
78}