metric_engine/
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 datatypes::prelude::ConcreteDataType;
21use snafu::{Location, Snafu};
22use store_api::region_request::RegionRequest;
23use store_api::storage::RegionId;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29    #[snafu(display("Failed to create mito region, region type: {}", region_type))]
30    CreateMitoRegion {
31        region_type: String,
32        source: BoxedError,
33        #[snafu(implicit)]
34        location: Location,
35    },
36
37    #[snafu(display("Failed to open mito region, region type: {}", region_type))]
38    OpenMitoRegion {
39        region_type: String,
40        source: BoxedError,
41        #[snafu(implicit)]
42        location: Location,
43    },
44
45    #[snafu(display("Failed to batch open mito region"))]
46    BatchOpenMitoRegion {
47        source: BoxedError,
48        #[snafu(implicit)]
49        location: Location,
50    },
51
52    #[snafu(display("Failed to close mito region, region id: {}", region_id))]
53    CloseMitoRegion {
54        region_id: RegionId,
55        source: BoxedError,
56        #[snafu(implicit)]
57        location: Location,
58    },
59
60    #[snafu(display("Failed to deserialize column metadata from {}", raw))]
61    DeserializeColumnMetadata {
62        raw: String,
63        #[snafu(source)]
64        error: serde_json::Error,
65        #[snafu(implicit)]
66        location: Location,
67    },
68
69    #[snafu(display("Failed to serialize column metadata"))]
70    SerializeColumnMetadata {
71        #[snafu(source)]
72        error: serde_json::Error,
73        #[snafu(implicit)]
74        location: Location,
75    },
76
77    #[snafu(display("Failed to serialize region manifest info"))]
78    SerializeRegionManifestInfo {
79        #[snafu(source)]
80        error: serde_json::Error,
81        #[snafu(implicit)]
82        location: Location,
83    },
84
85    #[snafu(display("Failed to decode base64 column value"))]
86    DecodeColumnValue {
87        #[snafu(source)]
88        error: base64::DecodeError,
89        #[snafu(implicit)]
90        location: Location,
91    },
92
93    #[snafu(display("Failed to parse region id from {}", raw))]
94    ParseRegionId {
95        raw: String,
96        #[snafu(source)]
97        error: <u64 as std::str::FromStr>::Err,
98        #[snafu(implicit)]
99        location: Location,
100    },
101
102    #[snafu(display("Failed to parse region options: {}", reason))]
103    ParseRegionOptions {
104        reason: String,
105        #[snafu(implicit)]
106        location: Location,
107    },
108
109    #[snafu(display("Mito read operation fails"))]
110    MitoReadOperation {
111        source: BoxedError,
112        #[snafu(implicit)]
113        location: Location,
114    },
115
116    #[snafu(display("Failed to encode primary key"))]
117    EncodePrimaryKey {
118        source: mito2::error::Error,
119        #[snafu(implicit)]
120        location: Location,
121    },
122
123    #[snafu(display("Mito write operation fails"))]
124    MitoWriteOperation {
125        source: BoxedError,
126        #[snafu(implicit)]
127        location: Location,
128    },
129
130    #[snafu(display("Mito flush operation fails"))]
131    MitoFlushOperation {
132        source: BoxedError,
133        #[snafu(implicit)]
134        location: Location,
135    },
136
137    #[snafu(display("Mito delete operation fails"))]
138    MitoDeleteOperation {
139        source: BoxedError,
140        #[snafu(implicit)]
141        location: Location,
142    },
143
144    #[snafu(display("Mito catchup operation fails"))]
145    MitoCatchupOperation {
146        source: BoxedError,
147        #[snafu(implicit)]
148        location: Location,
149    },
150
151    #[snafu(display("Mito sync operation fails"))]
152    MitoSyncOperation {
153        source: BoxedError,
154        #[snafu(implicit)]
155        location: Location,
156    },
157
158    #[snafu(display("Failed to collect record batch stream"))]
159    CollectRecordBatchStream {
160        source: common_recordbatch::error::Error,
161        #[snafu(implicit)]
162        location: Location,
163    },
164
165    #[snafu(display("Internal column {} is reserved", column))]
166    InternalColumnOccupied {
167        column: String,
168        #[snafu(implicit)]
169        location: Location,
170    },
171
172    #[snafu(display("Required table option is missing"))]
173    MissingRegionOption {
174        #[snafu(implicit)]
175        location: Location,
176    },
177
178    #[snafu(display("Region options are conflicted"))]
179    ConflictRegionOption {
180        #[snafu(implicit)]
181        location: Location,
182    },
183
184    #[snafu(display("Physical region {} not found", region_id))]
185    PhysicalRegionNotFound {
186        region_id: RegionId,
187        #[snafu(implicit)]
188        location: Location,
189    },
190
191    #[snafu(display("Logical region {} not found", region_id))]
192    LogicalRegionNotFound {
193        region_id: RegionId,
194        #[snafu(implicit)]
195        location: Location,
196    },
197
198    #[snafu(display("Column type mismatch. Expect {:?}, got {:?}", expect, actual))]
199    ColumnTypeMismatch {
200        expect: ConcreteDataType,
201        actual: ConcreteDataType,
202        #[snafu(implicit)]
203        location: Location,
204    },
205
206    #[snafu(display("Column {} not found in logical region {}", name, region_id))]
207    ColumnNotFound {
208        name: String,
209        region_id: RegionId,
210        #[snafu(implicit)]
211        location: Location,
212    },
213
214    #[snafu(display("Alter request to physical region is forbidden"))]
215    ForbiddenPhysicalAlter {
216        #[snafu(implicit)]
217        location: Location,
218    },
219
220    #[snafu(display("Invalid region metadata"))]
221    InvalidMetadata {
222        source: store_api::metadata::MetadataError,
223        #[snafu(implicit)]
224        location: Location,
225    },
226
227    #[snafu(display(
228        "Physical region {} is busy, there are still some logical regions using it",
229        region_id
230    ))]
231    PhysicalRegionBusy {
232        region_id: RegionId,
233        #[snafu(implicit)]
234        location: Location,
235    },
236
237    #[snafu(display("Unsupported region request: {}", request))]
238    UnsupportedRegionRequest {
239        request: Box<RegionRequest>,
240        #[snafu(implicit)]
241        location: Location,
242    },
243
244    #[snafu(display("Unsupported alter kind: {}", kind))]
245    UnsupportedAlterKind {
246        kind: String,
247        #[snafu(implicit)]
248        location: Location,
249    },
250
251    #[snafu(display("Multiple field column found: {} and {}", previous, current))]
252    MultipleFieldColumn {
253        previous: String,
254        current: String,
255        #[snafu(implicit)]
256        location: Location,
257    },
258
259    #[snafu(display("Adding field column {} to physical table", name))]
260    AddingFieldColumn {
261        name: String,
262        #[snafu(implicit)]
263        location: Location,
264    },
265
266    #[snafu(display("No field column found"))]
267    NoFieldColumn {
268        #[snafu(implicit)]
269        location: Location,
270    },
271
272    #[snafu(display("Failed to set SKIPPING index option"))]
273    SetSkippingIndexOption {
274        source: datatypes::error::Error,
275        #[snafu(implicit)]
276        location: Location,
277    },
278
279    #[snafu(display("Unexpected request: {}", reason))]
280    UnexpectedRequest {
281        reason: String,
282        #[snafu(implicit)]
283        location: Location,
284    },
285
286    #[snafu(display("Expected metric manifest info, region: {}", region_id))]
287    MetricManifestInfo {
288        region_id: RegionId,
289        #[snafu(implicit)]
290        location: Location,
291    },
292
293    #[snafu(display("Failed to start repeated task: {}", name))]
294    StartRepeatedTask {
295        name: String,
296        source: common_runtime::error::Error,
297        #[snafu(implicit)]
298        location: Location,
299    },
300}
301
302pub type Result<T, E = Error> = std::result::Result<T, E>;
303
304impl ErrorExt for Error {
305    fn status_code(&self) -> StatusCode {
306        use Error::*;
307
308        match self {
309            InternalColumnOccupied { .. }
310            | MissingRegionOption { .. }
311            | ConflictRegionOption { .. }
312            | ColumnTypeMismatch { .. }
313            | PhysicalRegionBusy { .. }
314            | MultipleFieldColumn { .. }
315            | NoFieldColumn { .. }
316            | AddingFieldColumn { .. }
317            | ParseRegionOptions { .. }
318            | UnexpectedRequest { .. }
319            | UnsupportedAlterKind { .. } => StatusCode::InvalidArguments,
320
321            ForbiddenPhysicalAlter { .. } | UnsupportedRegionRequest { .. } => {
322                StatusCode::Unsupported
323            }
324
325            DeserializeColumnMetadata { .. }
326            | SerializeColumnMetadata { .. }
327            | DecodeColumnValue { .. }
328            | ParseRegionId { .. }
329            | InvalidMetadata { .. }
330            | SetSkippingIndexOption { .. }
331            | SerializeRegionManifestInfo { .. } => StatusCode::Unexpected,
332
333            PhysicalRegionNotFound { .. } | LogicalRegionNotFound { .. } => {
334                StatusCode::RegionNotFound
335            }
336
337            ColumnNotFound { .. } => StatusCode::TableColumnNotFound,
338
339            CreateMitoRegion { source, .. }
340            | OpenMitoRegion { source, .. }
341            | CloseMitoRegion { source, .. }
342            | MitoReadOperation { source, .. }
343            | MitoWriteOperation { source, .. }
344            | MitoCatchupOperation { source, .. }
345            | MitoFlushOperation { source, .. }
346            | MitoDeleteOperation { source, .. }
347            | MitoSyncOperation { source, .. }
348            | BatchOpenMitoRegion { source, .. } => source.status_code(),
349
350            EncodePrimaryKey { source, .. } => source.status_code(),
351
352            CollectRecordBatchStream { source, .. } => source.status_code(),
353
354            StartRepeatedTask { source, .. } => source.status_code(),
355
356            MetricManifestInfo { .. } => StatusCode::Internal,
357        }
358    }
359
360    fn as_any(&self) -> &dyn Any {
361        self
362    }
363}