Skip to main content

partition/
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, RetryHint};
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use datafusion_common::ScalarValue;
21use datatypes::arrow;
22use datatypes::prelude::Value;
23use snafu::{Location, Snafu};
24use store_api::storage::RegionId;
25use table::metadata::TableId;
26
27use crate::expr::{Operand, PartitionExpr};
28
29#[derive(Snafu)]
30#[snafu(visibility(pub))]
31#[stack_trace_debug]
32pub enum Error {
33    #[snafu(display("Failed to find table route: {}", table_id))]
34    TableRouteNotFound {
35        table_id: TableId,
36        #[snafu(implicit)]
37        location: Location,
38    },
39
40    #[snafu(display("Table route manager error"))]
41    TableRouteManager {
42        source: common_meta::error::Error,
43        #[snafu(implicit)]
44        location: Location,
45    },
46
47    #[snafu(display("Failed to get partition info"))]
48    GetPartitionInfo {
49        source: common_meta::error::Error,
50        #[snafu(implicit)]
51        location: Location,
52    },
53
54    #[snafu(display("Failed to get meta info from cache, error: {}", err_msg))]
55    GetCache {
56        err_msg: String,
57        #[snafu(implicit)]
58        location: Location,
59    },
60
61    #[snafu(display(
62        "Failed to find region routes for table {}, region id: {}",
63        table_id,
64        region_id
65    ))]
66    FindRegionRoutes {
67        table_id: TableId,
68        region_id: u64,
69        #[snafu(implicit)]
70        location: Location,
71    },
72
73    #[snafu(display("Failed to serialize value to json"))]
74    SerializeJson {
75        #[snafu(source)]
76        error: serde_json::Error,
77        #[snafu(implicit)]
78        location: Location,
79    },
80
81    #[snafu(display("Failed to deserialize value from json"))]
82    DeserializeJson {
83        #[snafu(source)]
84        error: serde_json::Error,
85        #[snafu(implicit)]
86        location: Location,
87    },
88
89    #[snafu(display("Expect {} region keys, actual {}", expect, actual))]
90    RegionKeysSize {
91        expect: usize,
92        actual: usize,
93        #[snafu(implicit)]
94        location: Location,
95    },
96
97    #[snafu(display("Invalid InsertRequest, reason: {}", reason))]
98    InvalidInsertRequest {
99        reason: String,
100        #[snafu(implicit)]
101        location: Location,
102    },
103
104    #[snafu(display("Invalid DeleteRequest, reason: {}", reason))]
105    InvalidDeleteRequest {
106        reason: String,
107        #[snafu(implicit)]
108        location: Location,
109    },
110
111    #[snafu(display("Failed to convert DataFusion's ScalarValue: {:?}", value))]
112    ConvertScalarValue {
113        value: ScalarValue,
114        #[snafu(implicit)]
115        location: Location,
116        source: datatypes::error::Error,
117    },
118
119    #[snafu(display("Failed to find leader of table id {} region {}", table_id, region_id))]
120    FindLeader {
121        table_id: TableId,
122        region_id: RegionId,
123        #[snafu(implicit)]
124        location: Location,
125    },
126
127    #[snafu(display("Unexpected table route type: {}", err_msg))]
128    UnexpectedLogicalRouteTable {
129        #[snafu(implicit)]
130        location: Location,
131        err_msg: String,
132        source: common_meta::error::Error,
133    },
134
135    #[snafu(display("Invalid partition expr: {:?}", expr))]
136    InvalidExpr {
137        expr: PartitionExpr,
138        #[snafu(implicit)]
139        location: Location,
140    },
141
142    #[snafu(display("Unexpected operand: {:?}, want Expr", operand))]
143    NoExprOperand {
144        operand: Operand,
145        #[snafu(implicit)]
146        location: Location,
147    },
148
149    #[snafu(display("Undefined column: {}", column))]
150    UndefinedColumn {
151        column: String,
152        #[snafu(implicit)]
153        location: Location,
154    },
155
156    #[snafu(display("Unexpected: {err_msg}"))]
157    Unexpected {
158        err_msg: String,
159        #[snafu(implicit)]
160        location: Location,
161    },
162
163    #[snafu(display("Failed to convert to vector"))]
164    ConvertToVector {
165        source: datatypes::error::Error,
166        #[snafu(implicit)]
167        location: Location,
168    },
169
170    #[snafu(display("Failed to evaluate record batch"))]
171    EvaluateRecordBatch {
172        #[snafu(source)]
173        error: datafusion_common::error::DataFusionError,
174        #[snafu(implicit)]
175        location: Location,
176    },
177
178    #[snafu(display("Failed to compute arrow kernel"))]
179    ComputeArrowKernel {
180        #[snafu(source)]
181        error: arrow::error::ArrowError,
182        #[snafu(implicit)]
183        location: Location,
184    },
185
186    #[snafu(display("Unexpected evaluation result column type: {}", data_type))]
187    UnexpectedColumnType {
188        data_type: arrow::datatypes::DataType,
189        #[snafu(implicit)]
190        location: Location,
191    },
192
193    #[snafu(display("Failed to convert to DataFusion's Schema"))]
194    ToDFSchema {
195        #[snafu(source)]
196        error: datafusion_common::error::DataFusionError,
197        #[snafu(implicit)]
198        location: Location,
199    },
200
201    #[snafu(display("Failed to create physical expression"))]
202    CreatePhysicalExpr {
203        #[snafu(source)]
204        error: datafusion_common::error::DataFusionError,
205        #[snafu(implicit)]
206        location: Location,
207    },
208
209    #[snafu(display("Failed to coerce partition expr against the schema"))]
210    CoercePartitionExpr {
211        #[snafu(source)]
212        error: datafusion_common::error::DataFusionError,
213        #[snafu(implicit)]
214        location: Location,
215    },
216
217    #[snafu(display("Partition expr value is not supported: {:?}", value))]
218    UnsupportedPartitionExprValue {
219        value: Value,
220        #[snafu(implicit)]
221        location: Location,
222    },
223
224    #[snafu(display("Failed to convert partition expr value to ScalarValue: {:?}", value))]
225    ConvertPartitionExprValue {
226        value: Value,
227        #[snafu(implicit)]
228        location: Location,
229        source: datatypes::error::Error,
230    },
231
232    #[snafu(display("Duplicate expr: {:?}", expr))]
233    DuplicateExpr {
234        expr: PartitionExpr,
235        #[snafu(implicit)]
236        location: Location,
237    },
238
239    #[snafu(display("Checkpoint `{}` is not covered", checkpoint))]
240    CheckpointNotCovered {
241        checkpoint: String,
242        #[snafu(implicit)]
243        location: Location,
244    },
245
246    #[snafu(display("Checkpoint `{}` is overlapped", checkpoint))]
247    CheckpointOverlapped {
248        checkpoint: String,
249        #[snafu(implicit)]
250        location: Location,
251    },
252}
253
254impl ErrorExt for Error {
255    fn status_code(&self) -> StatusCode {
256        match self {
257            Error::GetCache { .. } => StatusCode::StorageUnavailable,
258            Error::FindLeader { .. } => StatusCode::TableUnavailable,
259
260            Error::InvalidExpr { .. }
261            | Error::NoExprOperand { .. }
262            | Error::UndefinedColumn { .. }
263            | Error::DuplicateExpr { .. }
264            | Error::CheckpointNotCovered { .. }
265            | Error::CheckpointOverlapped { .. } => StatusCode::InvalidArguments,
266
267            Error::RegionKeysSize { .. }
268            | Error::InvalidInsertRequest { .. }
269            | Error::InvalidDeleteRequest { .. } => StatusCode::InvalidArguments,
270
271            Error::ConvertScalarValue { .. }
272            | Error::SerializeJson { .. }
273            | Error::DeserializeJson { .. } => StatusCode::Internal,
274
275            Error::Unexpected { .. } | Error::FindRegionRoutes { .. } => StatusCode::Unexpected,
276            Error::TableRouteNotFound { .. } => StatusCode::TableNotFound,
277            Error::TableRouteManager { source, .. } => source.status_code(),
278            Error::GetPartitionInfo { source, .. } => source.status_code(),
279            Error::UnexpectedLogicalRouteTable { source, .. } => source.status_code(),
280            Error::ConvertToVector { source, .. } => source.status_code(),
281            Error::EvaluateRecordBatch { .. } => StatusCode::Internal,
282            Error::ComputeArrowKernel { .. } => StatusCode::Internal,
283            Error::UnexpectedColumnType { .. } => StatusCode::Internal,
284            Error::ToDFSchema { .. } => StatusCode::Internal,
285            Error::CreatePhysicalExpr { .. } => StatusCode::Internal,
286            Error::CoercePartitionExpr { .. } => StatusCode::Internal,
287            Error::UnsupportedPartitionExprValue { .. } => StatusCode::InvalidArguments,
288            Error::ConvertPartitionExprValue { .. } => StatusCode::InvalidArguments,
289        }
290    }
291
292    fn as_any(&self) -> &dyn Any {
293        self
294    }
295
296    fn retry_hint(&self) -> RetryHint {
297        match self {
298            Error::GetCache { .. } | Error::FindLeader { .. } => RetryHint::Retryable,
299            Error::TableRouteManager { source, .. }
300            | Error::GetPartitionInfo { source, .. }
301            | Error::UnexpectedLogicalRouteTable { source, .. } => source.retry_hint(),
302            Error::ConvertToVector { source, .. } => source.retry_hint(),
303            _ => RetryHint::NonRetryable,
304        }
305    }
306}
307
308pub type Result<T> = std::result::Result<T, Error>;