1use std::time::Duration;
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
9pub enum Error {
10 #[error("authentication failed: {message}")]
12 Authentication {
13 message: String,
14 status: u16,
15 code: Option<String>,
16 },
17
18 #[error("insufficient credits: balance={balance}, required={required} ({message})")]
21 InsufficientCredits {
22 message: String,
23 status: u16,
24 code: Option<String>,
25 balance: i64,
26 required: i64,
27 },
28
29 #[error("invalid request: {message}")]
31 InvalidRequest {
32 message: String,
33 status: u16,
34 code: Option<String>,
35 },
36
37 #[error("rate limited (retry_after={retry_after:?}): {message}")]
40 RateLimit {
41 message: String,
42 status: u16,
43 code: Option<String>,
44 retry_after: Duration,
45 },
46
47 #[error("job failed: {reason} (job_id={job_id:?})")]
49 JobFailed {
50 job_id: Option<String>,
51 reason: String,
52 },
53
54 #[error("polling timed out after {elapsed:?} (job_id={job_id:?})")]
56 JobTimeout {
57 job_id: Option<String>,
58 elapsed: Duration,
59 },
60
61 #[error("server error {status}: {message}")]
63 Server {
64 message: String,
65 status: u16,
66 code: Option<String>,
67 },
68
69 #[error("network error: {message}")]
71 Network {
72 message: String,
73 #[source]
74 source: Option<Box<dyn std::error::Error + Send + Sync>>,
75 },
76
77 #[error("anakin: {0}")]
79 Other(String),
80}
81
82impl Error {
83 pub fn status(&self) -> u16 {
85 match self {
86 Error::Authentication { status, .. }
87 | Error::InsufficientCredits { status, .. }
88 | Error::InvalidRequest { status, .. }
89 | Error::RateLimit { status, .. }
90 | Error::Server { status, .. } => *status,
91 _ => 0,
92 }
93 }
94
95 pub fn code(&self) -> Option<&str> {
97 match self {
98 Error::Authentication { code, .. }
99 | Error::InsufficientCredits { code, .. }
100 | Error::InvalidRequest { code, .. }
101 | Error::RateLimit { code, .. }
102 | Error::Server { code, .. } => code.as_deref(),
103 _ => None,
104 }
105 }
106}
107
108pub type Result<T> = std::result::Result<T, Error>;