Skip to main content

auths_cli/errors/
cli_error.rs

1//! Typed CLI error variants with actionable help text.
2
3/// Structured CLI errors with built-in suggestion and documentation links.
4#[derive(thiserror::Error, Debug)]
5pub enum CliError {
6    #[error("key rotation failed — no pre-rotation commitment found")]
7    NoPrerotationCommitment,
8
9    #[error("identity not found — run `auths init` to create one")]
10    IdentityNotFound,
11
12    #[error("keychain unavailable — set AUTHS_KEYCHAIN_BACKEND=file for headless environments")]
13    KeychainUnavailable,
14
15    #[error("device key '{alias}' not found — import it first with `auths key import`")]
16    DeviceKeyNotFound { alias: String },
17
18    #[error("passphrase required — set AUTHS_PASSPHRASE env var for CI environments")]
19    PassphraseRequired,
20
21    #[error("attestation expired — issue a new one with `auths device link`")]
22    AttestationExpired,
23
24    #[error("capability '{capability}' not granted — check device authorization policies")]
25    MissingCapability { capability: String },
26}
27
28impl CliError {
29    /// Human-readable suggestion for how to recover from this error.
30    pub fn suggestion(&self) -> &str {
31        match self {
32            Self::NoPrerotationCommitment => {
33                "Run: auths key precommit --next-key <path-to-next-pubkey>"
34            }
35            Self::IdentityNotFound => "Run: auths init",
36            Self::KeychainUnavailable => {
37                "Set AUTHS_KEYCHAIN_BACKEND=file and AUTHS_PASSPHRASE=<passphrase> in your environment."
38            }
39            Self::DeviceKeyNotFound { .. } => "Run: auths key import --alias <alias> --file <path>",
40            Self::PassphraseRequired => {
41                "Set AUTHS_PASSPHRASE=<your-passphrase> in the environment, or run interactively."
42            }
43            Self::AttestationExpired => "Run: auths device link --device-alias <name>",
44            Self::MissingCapability { .. } => {
45                "Run: auths device link --capability <cap> to add the capability."
46            }
47        }
48    }
49
50    /// Documentation URL for this error, if available.
51    ///
52    /// These URLs map to Markdown source files under `docs/guides/` in this repository
53    /// (e.g., `docs/guides/key-rotation.md`). Keep the slugs in sync with those filenames
54    /// so static site generators (e.g., mdBook, Docusaurus) can serve them correctly.
55    pub fn docs_url(&self) -> Option<&str> {
56        match self {
57            Self::NoPrerotationCommitment => Some("https://docs.auths.dev/guides/key-rotation"),
58            Self::IdentityNotFound => Some("https://docs.auths.dev/guides/getting-started"),
59            Self::KeychainUnavailable => Some("https://docs.auths.dev/guides/headless-setup"),
60            _ => None,
61        }
62    }
63}