replicate_client/
error.rs1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Error, Debug)]
10pub enum Error {
11 #[error("HTTP request failed: {0}")]
13 Http(#[from] reqwest::Error),
14
15 #[error("HTTP middleware error: {0}")]
17 HttpMiddleware(#[from] reqwest_middleware::Error),
18
19 #[error("JSON error: {0}")]
21 Json(#[from] serde_json::Error),
22
23 #[error("API error: {status} - {message}")]
25 Api {
26 status: u16,
27 message: String,
28 detail: Option<String>,
29 },
30
31 #[error("Authentication error: {0}")]
33 Auth(String),
34
35 #[error("Invalid input: {0}")]
37 InvalidInput(String),
38
39 #[error("File error: {0}")]
41 File(#[from] std::io::Error),
42
43 #[error("URL error: {0}")]
45 Url(#[from] url::ParseError),
46
47 #[error("Model execution failed: {prediction_id}")]
49 ModelExecution {
50 prediction_id: String,
51 error_message: Option<String>,
52 logs: Option<String>,
53 },
54
55 #[error("Operation timed out: {0}")]
57 Timeout(String),
58
59 #[error("Unsupported operation: {0}")]
61 Unsupported(String),
62}
63
64impl Error {
65 pub fn api_error(status: u16, message: impl Into<String>) -> Self {
67 Self::Api {
68 status,
69 message: message.into(),
70 detail: None,
71 }
72 }
73
74 pub fn api_error_with_detail(
76 status: u16,
77 message: impl Into<String>,
78 detail: impl Into<String>,
79 ) -> Self {
80 Self::Api {
81 status,
82 message: message.into(),
83 detail: Some(detail.into()),
84 }
85 }
86
87 pub fn auth_error(message: impl Into<String>) -> Self {
89 Self::Auth(message.into())
90 }
91
92 pub fn invalid_input(message: impl Into<String>) -> Self {
94 Self::InvalidInput(message.into())
95 }
96
97 pub fn model_execution(
99 prediction_id: impl Into<String>,
100 error_message: Option<String>,
101 logs: Option<String>,
102 ) -> Self {
103 Self::ModelExecution {
104 prediction_id: prediction_id.into(),
105 error_message,
106 logs,
107 }
108 }
109
110 pub fn timeout(message: impl Into<String>) -> Self {
112 Self::Timeout(message.into())
113 }
114
115 pub fn unsupported(message: impl Into<String>) -> Self {
117 Self::Unsupported(message.into())
118 }
119}
120
121pub trait StatusCodeExt {
123 fn to_replicate_error(self, body: String) -> Error;
124}
125
126impl StatusCodeExt for reqwest::StatusCode {
127 fn to_replicate_error(self, body: String) -> Error {
128 match self.as_u16() {
129 401 => Error::auth_error("Invalid API token"),
130 402 => Error::auth_error("Insufficient credits"),
131 403 => Error::auth_error("Forbidden"),
132 404 => Error::api_error(404, "Resource not found"),
133 422 => Error::api_error_with_detail(422, "Validation error", body),
134 429 => Error::api_error(429, "Rate limit exceeded"),
135 500..=599 => Error::api_error(self.as_u16(), "Server error"),
136 _ => Error::api_error(self.as_u16(), body),
137 }
138 }
139}