1use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum ClientError {
7 #[error(
8 "pidge has not been provisioned yet. The maintainer needs to run scripts/register-pidge-app.sh and update APP_CLIENT_ID."
9 )]
10 NotProvisioned,
11
12 #[error("OS keychain unavailable: {0}")]
13 Keychain(#[from] keyring::Error),
14
15 #[error("could not determine the user config directory")]
16 NoConfigDir,
17
18 #[error("io: {0}")]
19 Io(#[from] std::io::Error),
20
21 #[error("device code flow: authorization pending exceeded poll deadline")]
22 DeviceCodeTimeout,
23
24 #[error("device code flow: user denied consent")]
25 DeviceCodeAccessDenied,
26
27 #[error("device code flow: {kind}{}", description.as_ref().map(|d| format!(" — {d}")).unwrap_or_default())]
28 DeviceCodeOther {
29 kind: String,
30 description: Option<String>,
31 },
32
33 #[error("session expired for {email}. Run `pidge account add` to re-add this account.")]
34 SessionExpired { email: String },
35
36 #[error("http: {0}")]
37 Http(#[from] reqwest::Error),
38
39 #[error("json: {0}")]
40 Json(#[from] serde_json::Error),
41
42 #[error("Microsoft Graph: {status} {message}")]
43 Graph { status: u16, message: String },
44
45 #[error(
46 "Microsoft Graph is throttling requests{}. Try again later.",
47 retry_after.map(|s| format!(" (retry after {s}s)")).unwrap_or_default()
48 )]
49 Throttled { retry_after: Option<u64> },
50
51 #[error("the delta cursor has expired — re-bootstrap without --cursor")]
52 DeltaExpired,
53
54 #[error("core: {0}")]
55 Core(#[from] pidge_core::CoreError),
56
57 #[error("token response missing access_token")]
58 MissingAccessToken,
59}