keygen_rs/
errors.rs

1use reqwest::header::InvalidHeaderValue;
2use serde_urlencoded::ser::Error as UrlEncodedError;
3use thiserror::Error;
4use url::ParseError;
5
6use crate::{license::License, license_file::LicenseFileDataset, machine_file::MachineFileDataset};
7
8#[derive(Error, Debug)]
9pub enum Error {
10    #[error("Unexpected error: {0}")]
11    UnexpectedError(String),
12
13    #[error("Invalid URL")]
14    InvalidUrl,
15
16    #[error("System clock is out of sync")]
17    SystemClockUnsynced,
18
19    #[error("Decryption error: {0}")]
20    DecryptionError(String),
21
22    #[error("HTTP client error: {0}")]
23    HttpClient(#[from] reqwest::Error),
24
25    #[error("URL parse error: {0}")]
26    UrlParse(#[from] ParseError),
27
28    #[error("JSON error: {0}")]
29    JsonError(#[from] serde_json::Error),
30
31    #[error("Invalid header value: {0}")]
32    InvalidHeader(#[from] InvalidHeaderValue),
33
34    #[error("URL encoding error: {0}")]
35    UrlEncode(#[from] UrlEncodedError),
36
37    #[error("Rate limit exceeded")]
38    RateLimitExceeded {
39        window: String,
40        count: u32,
41        limit: u32,
42        remaining: u32,
43        reset: u64,
44        retry_after: u64,
45    },
46
47    #[error("License key is missing")]
48    LicenseKeyMissing,
49
50    #[error("License scheme is missing")]
51    LicenseSchemeMissing,
52
53    #[error("License scheme is not supported")]
54    LicenseSchemeNotSupported,
55
56    #[error("License is not signed")]
57    LicenseNotSigned,
58
59    #[error("License key is not genuine")]
60    LicenseKeyNotGenuine,
61
62    #[error("Public key is missing")]
63    PublicKeyMissing,
64
65    #[error("Public key is invalid")]
66    PublicKeyInvalid,
67
68    #[error("License scheme unsupported")]
69    LicenseSchemeUnsupported,
70
71    #[error("{0}")]
72    CertificateFileInvalid(String),
73
74    #[error("{0}")]
75    CertificateFileNotGenuine(String),
76
77    #[error("{0}")]
78    CertificateFileNotSupported(String),
79
80    #[error("Certificate file expired")]
81    CertificateFileExpired,
82
83    #[error("License file invalid: {0}")]
84    LicenseFileInvalid(String),
85
86    #[error("License file not genuine: {0}")]
87    LicenseFileNotGenuine(String),
88
89    #[error("License file not supported: {0}")]
90    LicenseFileNotSupported(String),
91
92    #[error("License file not encrypted")]
93    LicenseFileNotEncrypted,
94
95    #[error("License file expired")]
96    LicenseFileExpired(Box<LicenseFileDataset>),
97
98    #[error("Machine file invalid")]
99    MachineFileInvalid(String),
100
101    #[error("Machine file not genuine")]
102    MachineFileNotGenuine(String),
103
104    #[error("Machine file not supported")]
105    MachineFileNotSupported(String),
106
107    #[error("License file expired")]
108    MachineFileExpired(Box<MachineFileDataset>),
109
110    #[error("API error: {detail}")]
111    KeygenApiError {
112        code: String,
113        detail: String,
114        body: serde_json::Value,
115    },
116
117    #[error("Token not allowed")]
118    TokenNotAllowed { code: String, detail: String },
119
120    #[error("Token format invalid")]
121    TokenFormatInvalid { code: String, detail: String },
122
123    #[error("Token invalid")]
124    TokenInvalid { code: String, detail: String },
125
126    #[error("Token expired")]
127    TokenExpired { code: String, detail: String },
128
129    #[error("License suspended")]
130    LicenseSuspended { code: String, detail: String },
131
132    #[error("License expired")]
133    LicenseExpired { code: String, detail: String },
134
135    #[error("License not allowed")]
136    LicenseNotAllowed { code: String, detail: String },
137
138    #[error("License not activated")]
139    LicenseNotActivated {
140        code: String,
141        detail: String,
142        license: Box<License>,
143    },
144
145    #[error("License key invalid")]
146    LicenseKeyInvalid { code: String, detail: String },
147
148    #[error("License token invalid")]
149    LicenseTokenInvalid { code: String, detail: String },
150
151    #[error("License has too many machines")]
152    LicenseTooManyMachines { code: String, detail: String },
153
154    #[error("License has too many cores")]
155    LicenseTooManyCores { code: String, detail: String },
156
157    #[error("License has too many processes")]
158    LicenseTooManyProcesses { code: String, detail: String },
159
160    #[error("Machine already activated")]
161    MachineAlreadyActivated { code: String, detail: String },
162
163    #[error("Machine limit exceeded")]
164    MachineLimitExceeded { code: String, detail: String },
165
166    #[error("Machine no longer exists")]
167    MachineNotFound,
168
169    #[error("Process limit exceeded")]
170    ProcessLimitExceeded { code: String, detail: String },
171
172    #[error("Process no longer exists")]
173    ProcessNotFound,
174
175    #[error("Component conflict")]
176    ComponentConflict { code: String, detail: String },
177
178    #[error("Component already activated")]
179    ComponentAlreadyActivated { code: String, detail: String },
180
181    #[error("Component is not activated")]
182    ComponentNotActivated { code: String, detail: String },
183
184    #[error("Environment error")]
185    EnvironmentError { code: String, detail: String },
186
187    #[error("Heartbeat dead")]
188    HeartbeatDead { code: String, detail: String },
189
190    #[error("Heartbeat ping failed")]
191    HeartbeatPingFailed { code: String, detail: String },
192
193    #[error("Heartbeat is required")]
194    HeartbeatRequired { code: String, detail: String },
195
196    #[error("Validation fingerprint scope is missing")]
197    ValidationFingerprintMissing { code: String, detail: String },
198
199    #[error("Validation components scope is missing")]
200    ValidationComponentsMissing { code: String, detail: String },
201
202    #[error("Validation product scope is missing")]
203    ValidationProductMissing { code: String, detail: String },
204
205    #[error("Not found")]
206    NotFound { code: String, detail: String },
207
208    #[error("Keygen signature validation failed: {reason}")]
209    KeygenSignatureInvalid { reason: String },
210
211    #[error("Keygen signature missing")]
212    KeygenSignatureMissing,
213
214    #[error("Configuration missing")]
215    MissingConfiguration,
216}
217
218pub trait ErrorMeta {
219    fn code(&self) -> String;
220    fn detail(&self) -> String;
221}
222
223impl ErrorMeta for Error {
224    fn code(&self) -> String {
225        match self {
226            Error::KeygenApiError { code, .. }
227            | Error::TokenNotAllowed { code, .. }
228            | Error::TokenFormatInvalid { code, .. }
229            | Error::TokenInvalid { code, .. }
230            | Error::TokenExpired { code, .. }
231            | Error::LicenseSuspended { code, .. }
232            | Error::LicenseExpired { code, .. }
233            | Error::LicenseNotAllowed { code, .. }
234            | Error::LicenseNotActivated { code, .. }
235            | Error::LicenseKeyInvalid { code, .. }
236            | Error::LicenseTokenInvalid { code, .. }
237            | Error::LicenseTooManyMachines { code, .. }
238            | Error::LicenseTooManyCores { code, .. }
239            | Error::LicenseTooManyProcesses { code, .. }
240            | Error::MachineAlreadyActivated { code, .. }
241            | Error::MachineLimitExceeded { code, .. }
242            | Error::ProcessLimitExceeded { code, .. }
243            | Error::ComponentConflict { code, .. }
244            | Error::ComponentAlreadyActivated { code, .. }
245            | Error::ComponentNotActivated { code, .. }
246            | Error::EnvironmentError { code, .. }
247            | Error::HeartbeatDead { code, .. }
248            | Error::HeartbeatPingFailed { code, .. }
249            | Error::HeartbeatRequired { code, .. }
250            | Error::ValidationFingerprintMissing { code, .. }
251            | Error::ValidationComponentsMissing { code, .. }
252            | Error::ValidationProductMissing { code, .. }
253            | Error::NotFound { code, .. } => code.to_string(),
254            _ => "ERROR".to_string(),
255        }
256    }
257
258    fn detail(&self) -> String {
259        match self {
260            Error::KeygenApiError { detail, .. }
261            | Error::TokenNotAllowed { detail, .. }
262            | Error::TokenFormatInvalid { detail, .. }
263            | Error::TokenInvalid { detail, .. }
264            | Error::TokenExpired { detail, .. }
265            | Error::LicenseSuspended { detail, .. }
266            | Error::LicenseExpired { detail, .. }
267            | Error::LicenseNotAllowed { detail, .. }
268            | Error::LicenseNotActivated { detail, .. }
269            | Error::LicenseKeyInvalid { detail, .. }
270            | Error::LicenseTokenInvalid { detail, .. }
271            | Error::LicenseTooManyMachines { detail, .. }
272            | Error::LicenseTooManyCores { detail, .. }
273            | Error::LicenseTooManyProcesses { detail, .. }
274            | Error::MachineAlreadyActivated { detail, .. }
275            | Error::MachineLimitExceeded { detail, .. }
276            | Error::ProcessLimitExceeded { detail, .. }
277            | Error::ComponentConflict { detail, .. }
278            | Error::ComponentAlreadyActivated { detail, .. }
279            | Error::ComponentNotActivated { detail, .. }
280            | Error::EnvironmentError { detail, .. }
281            | Error::HeartbeatDead { detail, .. }
282            | Error::HeartbeatPingFailed { detail, .. }
283            | Error::HeartbeatRequired { detail, .. }
284            | Error::ValidationFingerprintMissing { detail, .. }
285            | Error::ValidationComponentsMissing { detail, .. }
286            | Error::ValidationProductMissing { detail, .. }
287            | Error::NotFound { detail, .. } => detail.to_string(),
288            _ => self.to_string(),
289        }
290    }
291}