Skip to main content

cli/
error.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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::{RegionId, 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 provider"))]
72    StartWalProvider {
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("Failed to build create region request for region: {region_id}"))]
86    BuildCreateRegionRequest {
87        region_id: RegionId,
88        #[snafu(implicit)]
89        location: Location,
90        source: common_meta::error::Error,
91    },
92
93    #[snafu(display("Unexpected error: {}", msg))]
94    Unexpected {
95        msg: String,
96        #[snafu(implicit)]
97        location: Location,
98    },
99
100    #[snafu(display("Missing config, msg: {}", msg))]
101    MissingConfig {
102        msg: String,
103        #[snafu(implicit)]
104        location: Location,
105    },
106
107    #[snafu(display("Illegal config: {}", msg))]
108    IllegalConfig {
109        msg: String,
110        #[snafu(implicit)]
111        location: Location,
112    },
113
114    #[snafu(display("Failed to parse proxy options: {}", error))]
115    ParseProxyOpts {
116        #[snafu(source)]
117        error: reqwest::Error,
118        #[snafu(implicit)]
119        location: Location,
120    },
121
122    #[snafu(display("Failed to build reqwest client: {}", error))]
123    BuildClient {
124        #[snafu(implicit)]
125        location: Location,
126        #[snafu(source)]
127        error: reqwest::Error,
128    },
129
130    #[snafu(display("Failed to parse SQL: {}", sql))]
131    ParseSql {
132        sql: String,
133        #[snafu(implicit)]
134        location: Location,
135        source: query::error::Error,
136    },
137
138    #[snafu(display("Failed to plan statement"))]
139    PlanStatement {
140        #[snafu(implicit)]
141        location: Location,
142        source: query::error::Error,
143    },
144
145    #[snafu(display("Failed to load layered config"))]
146    LoadLayeredConfig {
147        #[snafu(source(from(common_config::error::Error, Box::new)))]
148        source: Box<common_config::error::Error>,
149        #[snafu(implicit)]
150        location: Location,
151    },
152
153    #[snafu(display("Failed to connect to Etcd at {etcd_addr}"))]
154    ConnectEtcd {
155        etcd_addr: String,
156        #[snafu(source)]
157        error: etcd_client::Error,
158        #[snafu(implicit)]
159        location: Location,
160    },
161
162    #[snafu(display("Failed to serde json"))]
163    SerdeJson {
164        #[snafu(source)]
165        error: serde_json::error::Error,
166        #[snafu(implicit)]
167        location: Location,
168    },
169
170    #[snafu(display("Failed to run http request: {reason}"))]
171    HttpQuerySql {
172        reason: String,
173        #[snafu(source)]
174        error: reqwest::Error,
175        #[snafu(implicit)]
176        location: Location,
177    },
178
179    #[snafu(display("Empty result from output"))]
180    EmptyResult {
181        #[snafu(implicit)]
182        location: Location,
183    },
184
185    #[snafu(display("Failed to manipulate file"))]
186    FileIo {
187        #[snafu(implicit)]
188        location: Location,
189        #[snafu(source)]
190        error: std::io::Error,
191    },
192
193    #[snafu(display("Failed to create directory {}", dir))]
194    CreateDir {
195        dir: String,
196        #[snafu(source)]
197        error: std::io::Error,
198    },
199
200    #[snafu(display("Failed to spawn thread"))]
201    SpawnThread {
202        #[snafu(source)]
203        error: std::io::Error,
204    },
205
206    #[snafu(display("Other error"))]
207    Other {
208        source: BoxedError,
209        #[snafu(implicit)]
210        location: Location,
211    },
212
213    #[snafu(display("Failed to build runtime"))]
214    BuildRuntime {
215        #[snafu(implicit)]
216        location: Location,
217        source: common_runtime::error::Error,
218    },
219
220    #[snafu(display("Failed to get cache from cache registry: {}", name))]
221    CacheRequired {
222        #[snafu(implicit)]
223        location: Location,
224        name: String,
225    },
226
227    #[snafu(display("Failed to build cache registry"))]
228    BuildCacheRegistry {
229        #[snafu(implicit)]
230        location: Location,
231        source: cache::error::Error,
232    },
233
234    #[snafu(display("Failed to initialize meta client"))]
235    MetaClientInit {
236        #[snafu(implicit)]
237        location: Location,
238        source: meta_client::error::Error,
239    },
240
241    #[snafu(display("Cannot find schema {schema} in catalog {catalog}"))]
242    SchemaNotFound {
243        catalog: String,
244        schema: String,
245        #[snafu(implicit)]
246        location: Location,
247    },
248
249    #[snafu(display("Table not found: {table_id}"))]
250    TableNotFound {
251        table_id: TableId,
252        #[snafu(implicit)]
253        location: Location,
254    },
255
256    #[snafu(display("OpenDAL operator failed"))]
257    OpenDal {
258        #[snafu(implicit)]
259        location: Location,
260        #[snafu(source)]
261        error: ObjectStoreError,
262    },
263
264    #[snafu(display("Output directory not set"))]
265    OutputDirNotSet {
266        #[snafu(implicit)]
267        location: Location,
268    },
269
270    #[snafu(display("Empty store addresses"))]
271    EmptyStoreAddrs {
272        #[snafu(implicit)]
273        location: Location,
274    },
275
276    #[snafu(display("Unsupported memory backend"))]
277    UnsupportedMemoryBackend {
278        #[snafu(implicit)]
279        location: Location,
280    },
281
282    #[snafu(display("File path invalid: {}", msg))]
283    InvalidFilePath {
284        msg: String,
285        #[snafu(implicit)]
286        location: Location,
287    },
288
289    #[snafu(display("Invalid arguments: {}", msg))]
290    InvalidArguments {
291        msg: String,
292        #[snafu(implicit)]
293        location: Location,
294    },
295
296    #[snafu(display("Failed to init backend"))]
297    InitBackend {
298        #[snafu(implicit)]
299        location: Location,
300        #[snafu(source)]
301        error: ObjectStoreError,
302    },
303
304    #[snafu(display("Covert column schemas to defs failed"))]
305    CovertColumnSchemasToDefs {
306        #[snafu(implicit)]
307        location: Location,
308        source: operator::error::Error,
309    },
310
311    #[snafu(display("Failed to send request to datanode: {}", peer))]
312    SendRequestToDatanode {
313        peer: Peer,
314        #[snafu(implicit)]
315        location: Location,
316        source: common_meta::error::Error,
317    },
318
319    #[snafu(display("Failed to get current directory"))]
320    GetCurrentDir {
321        #[snafu(implicit)]
322        location: Location,
323        #[snafu(source)]
324        error: std::io::Error,
325    },
326}
327
328pub type Result<T> = std::result::Result<T, Error>;
329
330impl ErrorExt for Error {
331    fn status_code(&self) -> StatusCode {
332        match self {
333            Error::InitMetadata { source, .. }
334            | Error::InitDdlManager { source, .. }
335            | Error::TableMetadata { source, .. }
336            | Error::BuildCreateRegionRequest { source, .. } => source.status_code(),
337
338            Error::MissingConfig { .. }
339            | Error::LoadLayeredConfig { .. }
340            | Error::IllegalConfig { .. }
341            | Error::InitTimezone { .. }
342            | Error::ConnectEtcd { .. }
343            | Error::CreateDir { .. }
344            | Error::EmptyResult { .. }
345            | Error::InvalidFilePath { .. }
346            | Error::UnsupportedMemoryBackend { .. }
347            | Error::InvalidArguments { .. }
348            | Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
349
350            Error::CovertColumnSchemasToDefs { source, .. } => source.status_code(),
351            Error::SendRequestToDatanode { source, .. } => source.status_code(),
352
353            Error::StartProcedureManager { source, .. }
354            | Error::StopProcedureManager { source, .. } => source.status_code(),
355            Error::StartWalProvider { source, .. } => source.status_code(),
356            Error::HttpQuerySql { .. } => StatusCode::Internal,
357            Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
358                source.status_code()
359            }
360            Error::Unexpected { .. } => StatusCode::Unexpected,
361
362            Error::SerdeJson { .. }
363            | Error::FileIo { .. }
364            | Error::SpawnThread { .. }
365            | Error::InitTlsProvider { .. }
366            | Error::BuildClient { .. } => StatusCode::Unexpected,
367
368            Error::Other { source, .. } => source.status_code(),
369            Error::OpenDal { .. } | Error::InitBackend { .. } => StatusCode::Internal,
370            Error::OutputDirNotSet { .. } | Error::EmptyStoreAddrs { .. } => {
371                StatusCode::InvalidArguments
372            }
373
374            Error::BuildRuntime { source, .. } => source.status_code(),
375
376            Error::CacheRequired { .. }
377            | Error::BuildCacheRegistry { .. }
378            | Error::GetCurrentDir { .. } => StatusCode::Internal,
379            Error::MetaClientInit { source, .. } => source.status_code(),
380            Error::TableNotFound { .. } => StatusCode::TableNotFound,
381            Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
382        }
383    }
384
385    fn as_any(&self) -> &dyn Any {
386        self
387    }
388}