1use std::any::Any;
16
17use common_error::ext::{BoxedError, ErrorExt};
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use common_meta::peer::Peer;
21use object_store::Error as ObjectStoreError;
22use snafu::{Location, Snafu};
23use store_api::storage::TableId;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29 #[snafu(display("Failed to install ring crypto provider: {}", msg))]
30 InitTlsProvider {
31 #[snafu(implicit)]
32 location: Location,
33 msg: String,
34 },
35
36 #[snafu(display("Failed to create default catalog and schema"))]
37 InitMetadata {
38 #[snafu(implicit)]
39 location: Location,
40 source: common_meta::error::Error,
41 },
42
43 #[snafu(display("Failed to init DDL manager"))]
44 InitDdlManager {
45 #[snafu(implicit)]
46 location: Location,
47 source: common_meta::error::Error,
48 },
49
50 #[snafu(display("Failed to init default timezone"))]
51 InitTimezone {
52 #[snafu(implicit)]
53 location: Location,
54 source: common_time::error::Error,
55 },
56
57 #[snafu(display("Failed to start procedure manager"))]
58 StartProcedureManager {
59 #[snafu(implicit)]
60 location: Location,
61 source: common_procedure::error::Error,
62 },
63
64 #[snafu(display("Failed to stop procedure manager"))]
65 StopProcedureManager {
66 #[snafu(implicit)]
67 location: Location,
68 source: common_procedure::error::Error,
69 },
70
71 #[snafu(display("Failed to start wal options allocator"))]
72 StartWalOptionsAllocator {
73 #[snafu(implicit)]
74 location: Location,
75 source: common_meta::error::Error,
76 },
77
78 #[snafu(display("Failed to get table metadata"))]
79 TableMetadata {
80 #[snafu(implicit)]
81 location: Location,
82 source: common_meta::error::Error,
83 },
84
85 #[snafu(display("Unexpected error: {}", msg))]
86 Unexpected {
87 msg: String,
88 #[snafu(implicit)]
89 location: Location,
90 },
91
92 #[snafu(display("Missing config, msg: {}", msg))]
93 MissingConfig {
94 msg: String,
95 #[snafu(implicit)]
96 location: Location,
97 },
98
99 #[snafu(display("Illegal config: {}", msg))]
100 IllegalConfig {
101 msg: String,
102 #[snafu(implicit)]
103 location: Location,
104 },
105
106 #[snafu(display("Failed to parse proxy options: {}", error))]
107 ParseProxyOpts {
108 #[snafu(source)]
109 error: reqwest::Error,
110 #[snafu(implicit)]
111 location: Location,
112 },
113
114 #[snafu(display("Failed to build reqwest client: {}", error))]
115 BuildClient {
116 #[snafu(implicit)]
117 location: Location,
118 #[snafu(source)]
119 error: reqwest::Error,
120 },
121
122 #[snafu(display("Failed to parse SQL: {}", sql))]
123 ParseSql {
124 sql: String,
125 #[snafu(implicit)]
126 location: Location,
127 source: query::error::Error,
128 },
129
130 #[snafu(display("Failed to plan statement"))]
131 PlanStatement {
132 #[snafu(implicit)]
133 location: Location,
134 source: query::error::Error,
135 },
136
137 #[snafu(display("Failed to load layered config"))]
138 LoadLayeredConfig {
139 #[snafu(source(from(common_config::error::Error, Box::new)))]
140 source: Box<common_config::error::Error>,
141 #[snafu(implicit)]
142 location: Location,
143 },
144
145 #[snafu(display("Failed to connect to Etcd at {etcd_addr}"))]
146 ConnectEtcd {
147 etcd_addr: String,
148 #[snafu(source)]
149 error: etcd_client::Error,
150 #[snafu(implicit)]
151 location: Location,
152 },
153
154 #[snafu(display("Failed to serde json"))]
155 SerdeJson {
156 #[snafu(source)]
157 error: serde_json::error::Error,
158 #[snafu(implicit)]
159 location: Location,
160 },
161
162 #[snafu(display("Failed to run http request: {reason}"))]
163 HttpQuerySql {
164 reason: String,
165 #[snafu(source)]
166 error: reqwest::Error,
167 #[snafu(implicit)]
168 location: Location,
169 },
170
171 #[snafu(display("Empty result from output"))]
172 EmptyResult {
173 #[snafu(implicit)]
174 location: Location,
175 },
176
177 #[snafu(display("Failed to manipulate file"))]
178 FileIo {
179 #[snafu(implicit)]
180 location: Location,
181 #[snafu(source)]
182 error: std::io::Error,
183 },
184
185 #[snafu(display("Failed to create directory {}", dir))]
186 CreateDir {
187 dir: String,
188 #[snafu(source)]
189 error: std::io::Error,
190 },
191
192 #[snafu(display("Failed to spawn thread"))]
193 SpawnThread {
194 #[snafu(source)]
195 error: std::io::Error,
196 },
197
198 #[snafu(display("Other error"))]
199 Other {
200 source: BoxedError,
201 #[snafu(implicit)]
202 location: Location,
203 },
204
205 #[snafu(display("Failed to build runtime"))]
206 BuildRuntime {
207 #[snafu(implicit)]
208 location: Location,
209 source: common_runtime::error::Error,
210 },
211
212 #[snafu(display("Failed to get cache from cache registry: {}", name))]
213 CacheRequired {
214 #[snafu(implicit)]
215 location: Location,
216 name: String,
217 },
218
219 #[snafu(display("Failed to build cache registry"))]
220 BuildCacheRegistry {
221 #[snafu(implicit)]
222 location: Location,
223 source: cache::error::Error,
224 },
225
226 #[snafu(display("Failed to initialize meta client"))]
227 MetaClientInit {
228 #[snafu(implicit)]
229 location: Location,
230 source: meta_client::error::Error,
231 },
232
233 #[snafu(display("Cannot find schema {schema} in catalog {catalog}"))]
234 SchemaNotFound {
235 catalog: String,
236 schema: String,
237 #[snafu(implicit)]
238 location: Location,
239 },
240
241 #[snafu(display("Table not found: {table_id}"))]
242 TableNotFound {
243 table_id: TableId,
244 #[snafu(implicit)]
245 location: Location,
246 },
247
248 #[snafu(display("OpenDAL operator failed"))]
249 OpenDal {
250 #[snafu(implicit)]
251 location: Location,
252 #[snafu(source)]
253 error: ObjectStoreError,
254 },
255
256 #[snafu(display("S3 config need be set"))]
257 S3ConfigNotSet {
258 #[snafu(implicit)]
259 location: Location,
260 },
261
262 #[snafu(display("Output directory not set"))]
263 OutputDirNotSet {
264 #[snafu(implicit)]
265 location: Location,
266 },
267
268 #[snafu(display("Empty store addresses"))]
269 EmptyStoreAddrs {
270 #[snafu(implicit)]
271 location: Location,
272 },
273
274 #[snafu(display("Unsupported memory backend"))]
275 UnsupportedMemoryBackend {
276 #[snafu(implicit)]
277 location: Location,
278 },
279
280 #[snafu(display("File path invalid: {}", msg))]
281 InvalidFilePath {
282 msg: String,
283 #[snafu(implicit)]
284 location: Location,
285 },
286
287 #[snafu(display("Invalid arguments: {}", msg))]
288 InvalidArguments {
289 msg: String,
290 #[snafu(implicit)]
291 location: Location,
292 },
293
294 #[snafu(display("Failed to init backend"))]
295 InitBackend {
296 #[snafu(implicit)]
297 location: Location,
298 #[snafu(source)]
299 error: ObjectStoreError,
300 },
301
302 #[snafu(display("Covert column schemas to defs failed"))]
303 CovertColumnSchemasToDefs {
304 #[snafu(implicit)]
305 location: Location,
306 source: operator::error::Error,
307 },
308
309 #[snafu(display("Failed to send request to datanode: {}", peer))]
310 SendRequestToDatanode {
311 peer: Peer,
312 #[snafu(implicit)]
313 location: Location,
314 source: common_meta::error::Error,
315 },
316}
317
318pub type Result<T> = std::result::Result<T, Error>;
319
320impl ErrorExt for Error {
321 fn status_code(&self) -> StatusCode {
322 match self {
323 Error::InitMetadata { source, .. }
324 | Error::InitDdlManager { source, .. }
325 | Error::TableMetadata { source, .. } => source.status_code(),
326
327 Error::MissingConfig { .. }
328 | Error::LoadLayeredConfig { .. }
329 | Error::IllegalConfig { .. }
330 | Error::InitTimezone { .. }
331 | Error::ConnectEtcd { .. }
332 | Error::CreateDir { .. }
333 | Error::EmptyResult { .. }
334 | Error::InvalidFilePath { .. }
335 | Error::UnsupportedMemoryBackend { .. }
336 | Error::InvalidArguments { .. }
337 | Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
338
339 Error::CovertColumnSchemasToDefs { source, .. } => source.status_code(),
340 Error::SendRequestToDatanode { source, .. } => source.status_code(),
341
342 Error::StartProcedureManager { source, .. }
343 | Error::StopProcedureManager { source, .. } => source.status_code(),
344 Error::StartWalOptionsAllocator { source, .. } => source.status_code(),
345 Error::HttpQuerySql { .. } => StatusCode::Internal,
346 Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
347 source.status_code()
348 }
349 Error::Unexpected { .. } => StatusCode::Unexpected,
350
351 Error::SerdeJson { .. }
352 | Error::FileIo { .. }
353 | Error::SpawnThread { .. }
354 | Error::InitTlsProvider { .. }
355 | Error::BuildClient { .. } => StatusCode::Unexpected,
356
357 Error::Other { source, .. } => source.status_code(),
358 Error::OpenDal { .. } | Error::InitBackend { .. } => StatusCode::Internal,
359 Error::S3ConfigNotSet { .. }
360 | Error::OutputDirNotSet { .. }
361 | Error::EmptyStoreAddrs { .. } => StatusCode::InvalidArguments,
362
363 Error::BuildRuntime { source, .. } => source.status_code(),
364
365 Error::CacheRequired { .. } | Error::BuildCacheRegistry { .. } => StatusCode::Internal,
366 Error::MetaClientInit { source, .. } => source.status_code(),
367 Error::TableNotFound { .. } => StatusCode::TableNotFound,
368 Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
369 }
370 }
371
372 fn as_any(&self) -> &dyn Any {
373 self
374 }
375}