Skip to main content

cli/data/export_v2/
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::ErrorExt;
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use snafu::{Location, Snafu};
21
22#[derive(Snafu)]
23#[snafu(visibility(pub))]
24#[stack_trace_debug]
25pub enum Error {
26    #[snafu(display("Invalid URI '{}': {}", uri, reason))]
27    InvalidUri {
28        uri: String,
29        reason: String,
30        #[snafu(implicit)]
31        location: Location,
32    },
33
34    #[snafu(display("Unsupported storage scheme: {}", scheme))]
35    UnsupportedScheme {
36        scheme: String,
37        #[snafu(implicit)]
38        location: Location,
39    },
40
41    #[snafu(display("Storage operation '{}' failed", operation))]
42    StorageOperation {
43        operation: String,
44        #[snafu(source)]
45        error: object_store::Error,
46        #[snafu(implicit)]
47        location: Location,
48    },
49
50    #[snafu(display("Failed to parse manifest"))]
51    ManifestParse {
52        #[snafu(source)]
53        error: serde_json::Error,
54        #[snafu(implicit)]
55        location: Location,
56    },
57
58    #[snafu(display("Failed to serialize manifest"))]
59    ManifestSerialize {
60        #[snafu(source)]
61        error: serde_json::Error,
62        #[snafu(implicit)]
63        location: Location,
64    },
65
66    #[snafu(display("Failed to decode text file as UTF-8"))]
67    TextDecode {
68        #[snafu(source)]
69        error: std::string::FromUtf8Error,
70        #[snafu(implicit)]
71        location: Location,
72    },
73
74    #[snafu(display(
75        "Cannot resume snapshot with a different schema_only mode (existing: {}, requested: {}). Use --force to recreate.",
76        existing_schema_only,
77        requested_schema_only
78    ))]
79    SchemaOnlyModeMismatch {
80        existing_schema_only: bool,
81        requested_schema_only: bool,
82        #[snafu(implicit)]
83        location: Location,
84    },
85
86    #[snafu(display(
87        "Cannot resume snapshot with different {} (existing: {}, requested: {}). Use --force to recreate.",
88        field,
89        existing,
90        requested
91    ))]
92    ResumeConfigMismatch {
93        field: String,
94        existing: String,
95        requested: String,
96        #[snafu(implicit)]
97        location: Location,
98    },
99
100    #[snafu(display("Failed to parse time: invalid format: {}", input))]
101    TimeParseInvalidFormat {
102        input: String,
103        #[snafu(implicit)]
104        location: Location,
105    },
106
107    #[snafu(display("Failed to parse time: end_time is before start_time"))]
108    TimeParseEndBeforeStart {
109        #[snafu(implicit)]
110        location: Location,
111    },
112
113    #[snafu(display(
114        "chunk_time_window requires both --start-time and --end-time to be specified"
115    ))]
116    ChunkTimeWindowRequiresBounds {
117        #[snafu(implicit)]
118        location: Location,
119    },
120
121    #[snafu(display("--schema-only cannot be used with data export arguments: {}", args))]
122    SchemaOnlyArgsNotAllowed {
123        args: String,
124        #[snafu(implicit)]
125        location: Location,
126    },
127
128    #[snafu(display("Empty result from query"))]
129    EmptyResult {
130        #[snafu(implicit)]
131        location: Location,
132    },
133
134    #[snafu(display("Unexpected value type in query result"))]
135    UnexpectedValueType {
136        #[snafu(implicit)]
137        location: Location,
138    },
139
140    #[snafu(display("Database error"))]
141    Database {
142        #[snafu(source)]
143        error: crate::error::Error,
144        #[snafu(implicit)]
145        location: Location,
146    },
147
148    #[snafu(display("Snapshot not found at '{}'", uri))]
149    SnapshotNotFound {
150        uri: String,
151        #[snafu(implicit)]
152        location: Location,
153    },
154
155    #[snafu(display("Schema '{}' not found in catalog '{}'", schema, catalog))]
156    SchemaNotFound {
157        catalog: String,
158        schema: String,
159        #[snafu(implicit)]
160        location: Location,
161    },
162
163    #[snafu(display("Failed to parse URL"))]
164    UrlParse {
165        #[snafu(source)]
166        error: url::ParseError,
167        #[snafu(implicit)]
168        location: Location,
169    },
170
171    #[snafu(display("Failed to build object store"))]
172    BuildObjectStore {
173        #[snafu(source)]
174        error: object_store::Error,
175        #[snafu(implicit)]
176        location: Location,
177    },
178
179    #[snafu(display("Manifest version mismatch: expected {}, found {}", expected, found))]
180    ManifestVersionMismatch {
181        expected: u32,
182        found: u32,
183        #[snafu(implicit)]
184        location: Location,
185    },
186}
187
188pub type Result<T> = std::result::Result<T, Error>;
189
190impl ErrorExt for Error {
191    fn status_code(&self) -> StatusCode {
192        match self {
193            Error::InvalidUri { .. }
194            | Error::UnsupportedScheme { .. }
195            | Error::SchemaOnlyModeMismatch { .. }
196            | Error::ResumeConfigMismatch { .. }
197            | Error::ManifestVersionMismatch { .. }
198            | Error::SchemaOnlyArgsNotAllowed { .. } => StatusCode::InvalidArguments,
199            Error::TimeParseInvalidFormat { .. }
200            | Error::TimeParseEndBeforeStart { .. }
201            | Error::ChunkTimeWindowRequiresBounds { .. } => StatusCode::InvalidArguments,
202
203            Error::StorageOperation { .. }
204            | Error::ManifestParse { .. }
205            | Error::ManifestSerialize { .. }
206            | Error::TextDecode { .. }
207            | Error::BuildObjectStore { .. } => StatusCode::StorageUnavailable,
208
209            Error::EmptyResult { .. }
210            | Error::UnexpectedValueType { .. }
211            | Error::UrlParse { .. } => StatusCode::Internal,
212
213            Error::Database { error, .. } => error.status_code(),
214
215            Error::SnapshotNotFound { .. } => StatusCode::InvalidArguments,
216            Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
217        }
218    }
219
220    fn as_any(&self) -> &dyn Any {
221        self
222    }
223}