1use std::any::Any;
16
17use common_error::ext::ErrorExt;
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 meta info from cache, error: {}", err_msg))]
48 GetCache {
49 err_msg: String,
50 #[snafu(implicit)]
51 location: Location,
52 },
53
54 #[snafu(display("Failed to find table routes for table id {}", table_id))]
55 FindTableRoutes {
56 table_id: TableId,
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("Partition expr value is not supported: {:?}", value))]
210 UnsupportedPartitionExprValue {
211 value: Value,
212 #[snafu(implicit)]
213 location: Location,
214 },
215
216 #[snafu(display("Duplicate expr: {:?}", expr))]
217 DuplicateExpr {
218 expr: PartitionExpr,
219 #[snafu(implicit)]
220 location: Location,
221 },
222
223 #[snafu(display("Checkpoint `{}` is not covered", checkpoint))]
224 CheckpointNotCovered {
225 checkpoint: String,
226 #[snafu(implicit)]
227 location: Location,
228 },
229
230 #[snafu(display("Checkpoint `{}` is overlapped", checkpoint))]
231 CheckpointOverlapped {
232 checkpoint: String,
233 #[snafu(implicit)]
234 location: Location,
235 },
236}
237
238impl ErrorExt for Error {
239 fn status_code(&self) -> StatusCode {
240 match self {
241 Error::GetCache { .. } => StatusCode::StorageUnavailable,
242 Error::FindLeader { .. } => StatusCode::TableUnavailable,
243
244 Error::InvalidExpr { .. }
245 | Error::NoExprOperand { .. }
246 | Error::UndefinedColumn { .. }
247 | Error::DuplicateExpr { .. }
248 | Error::CheckpointNotCovered { .. }
249 | Error::CheckpointOverlapped { .. } => StatusCode::InvalidArguments,
250
251 Error::RegionKeysSize { .. }
252 | Error::InvalidInsertRequest { .. }
253 | Error::InvalidDeleteRequest { .. } => StatusCode::InvalidArguments,
254
255 Error::ConvertScalarValue { .. }
256 | Error::SerializeJson { .. }
257 | Error::DeserializeJson { .. } => StatusCode::Internal,
258
259 Error::Unexpected { .. }
260 | Error::FindTableRoutes { .. }
261 | Error::FindRegionRoutes { .. } => StatusCode::Unexpected,
262 Error::TableRouteNotFound { .. } => StatusCode::TableNotFound,
263 Error::TableRouteManager { source, .. } => source.status_code(),
264 Error::UnexpectedLogicalRouteTable { source, .. } => source.status_code(),
265 Error::ConvertToVector { source, .. } => source.status_code(),
266 Error::EvaluateRecordBatch { .. } => StatusCode::Internal,
267 Error::ComputeArrowKernel { .. } => StatusCode::Internal,
268 Error::UnexpectedColumnType { .. } => StatusCode::Internal,
269 Error::ToDFSchema { .. } => StatusCode::Internal,
270 Error::CreatePhysicalExpr { .. } => StatusCode::Internal,
271 Error::UnsupportedPartitionExprValue { .. } => StatusCode::InvalidArguments,
272 }
273 }
274
275 fn as_any(&self) -> &dyn Any {
276 self
277 }
278}
279
280pub type Result<T> = std::result::Result<T, Error>;