1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum CliError {
5 #[error("Authentication failed: {0}")]
6 AuthError(String),
7
8 #[error("API error: {0}")]
9 ApiError(String),
10
11 #[error("Configuration error: {0}")]
12 ConfigError(String),
13
14 #[error("Not logged in. Run 'oauth-db login' first")]
15 NotLoggedIn,
16
17 #[error("Permission denied: {0}")]
18 PermissionDenied(String),
19
20 #[error("Permission denied for operation '{operation}'.\nrequired role: {required}\nYour role: {current}\n{hint}")]
21 RoleMissing {
22 current: String,
23 required: String,
24 operation: String,
25 hint: String,
26 },
27
28 #[error("Resource not found: {0}")]
29 NotFound(String),
30
31 #[error("Invalid input: {0}")]
32 InvalidInput(String),
33
34 #[error("HTTP request failed: {0}")]
35 HttpError(#[from] reqwest::Error),
36
37 #[error("IO error: {0}")]
38 IoError(#[from] std::io::Error),
39
40 #[error("Serialization error: {0}")]
41 SerdeError(#[from] serde_json::Error),
42
43 #[error("TOML error: {0}")]
44 TomlError(#[from] toml::de::Error),
45
46 #[error("Encryption error: {0}")]
47 CryptoError(String),
48
49 #[error("Encryption error: {0}")]
50 EncryptionError(String),
51
52 #[error("Serialization error: {0}")]
53 SerializationError(String),
54
55 #[error("Network error: {0}")]
56 NetworkError(String),
57}
58
59impl From<serde_yaml::Error> for CliError {
60 fn from(err: serde_yaml::Error) -> Self {
61 CliError::SerializationError(format!("YAML error: {}", err))
62 }
63}
64
65impl From<toml::ser::Error> for CliError {
66 fn from(err: toml::ser::Error) -> Self {
67 CliError::ConfigError(format!("TOML serialization error: {}", err))
68 }
69}
70
71pub type Result<T> = std::result::Result<T, CliError>;
72
73impl CliError {
74 pub fn role_missing(current: impl Into<String>, required: impl Into<String>, operation: impl Into<String>) -> Self {
76 let current = current.into();
77 let required = required.into();
78 let operation = operation.into();
79
80 let hint = match required.as_str() {
81 "admin" => "Please switch to an account with admin privileges or contact your administrator.",
82 "developer" => "You need to register as a developer. Run 'oauth-db register' to create an account.",
83 _ => "Please check your account permissions.",
84 };
85
86 CliError::RoleMissing {
87 current,
88 required,
89 operation,
90 hint: hint.to_string(),
91 }
92 }
93
94 pub fn permission_denied(resource: impl Into<String>, action: impl Into<String>) -> Self {
96 CliError::PermissionDenied(format!(
97 "You don't have permission to {} {}. Please check your access rights.",
98 action.into(),
99 resource.into()
100 ))
101 }
102}