1use std::any::Any;
16use std::io::Error as IoError;
17
18use common_error::ext::{BoxedError, ErrorExt};
19use common_error::status_code::StatusCode;
20use common_macro::stack_trace_debug;
21use snafu::{Location, Snafu};
22
23use crate::inverted_index::search::predicate::Predicate;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29 #[snafu(display("Failed to read"))]
30 Read {
31 #[snafu(source)]
32 error: IoError,
33 #[snafu(implicit)]
34 location: Location,
35 },
36
37 #[snafu(display("Failed to write"))]
38 Write {
39 #[snafu(source)]
40 error: IoError,
41 #[snafu(implicit)]
42 location: Location,
43 },
44
45 #[snafu(display("Failed to flush"))]
46 Flush {
47 #[snafu(source)]
48 error: IoError,
49 #[snafu(implicit)]
50 location: Location,
51 },
52
53 #[snafu(display("Failed to close"))]
54 Close {
55 #[snafu(source)]
56 error: IoError,
57 #[snafu(implicit)]
58 location: Location,
59 },
60
61 #[snafu(display(
62 "Unexpected inverted index blob size, min: {min_blob_size}, actual: {actual_blob_size}"
63 ))]
64 UnexpectedBlobSize {
65 min_blob_size: u64,
66 actual_blob_size: u64,
67 #[snafu(implicit)]
68 location: Location,
69 },
70
71 #[snafu(display("Blob size too small"))]
72 BlobSizeTooSmall {
73 #[snafu(implicit)]
74 location: Location,
75 },
76
77 #[snafu(display("Invalid footer payload size"))]
78 InvalidFooterPayloadSize {
79 #[snafu(implicit)]
80 location: Location,
81 },
82
83 #[snafu(display("Unexpected inverted index footer payload size, max: {max_payload_size}, actual: {actual_payload_size}"))]
84 UnexpectedFooterPayloadSize {
85 max_payload_size: u64,
86 actual_payload_size: u64,
87 #[snafu(implicit)]
88 location: Location,
89 },
90
91 #[snafu(display("Unexpected inverted index offset size, offset: {offset}, size: {size}, blob_size: {blob_size}, payload_size: {payload_size}"))]
92 UnexpectedOffsetSize {
93 offset: u64,
94 size: u64,
95 blob_size: u64,
96 payload_size: u64,
97 },
98
99 #[snafu(display("Unexpected zero segment row count"))]
100 UnexpectedZeroSegmentRowCount {
101 #[snafu(implicit)]
102 location: Location,
103 },
104
105 #[snafu(display("Failed to decode fst"))]
106 DecodeFst {
107 #[snafu(source)]
108 error: fst::Error,
109 #[snafu(implicit)]
110 location: Location,
111 },
112
113 #[snafu(display("Failed to decode bitmap"))]
114 DecodeBitmap {
115 #[snafu(source)]
116 error: IoError,
117 #[snafu(implicit)]
118 location: Location,
119 },
120
121 #[snafu(display("Failed to decode protobuf"))]
122 DecodeProto {
123 #[snafu(source)]
124 error: prost::DecodeError,
125 #[snafu(implicit)]
126 location: Location,
127 },
128
129 #[snafu(display("Failed to parse regex pattern: {pattern}"))]
130 ParseRegex {
131 #[snafu(source)]
132 error: regex::Error,
133 pattern: String,
134 #[snafu(implicit)]
135 location: Location,
136 },
137
138 #[snafu(display("Failed to parse regex DFA"))]
139 ParseDFA {
140 #[snafu(source)]
141 error: Box<regex_automata::dfa::dense::BuildError>,
142 #[snafu(implicit)]
143 location: Location,
144 },
145
146 #[snafu(display("Unexpected empty predicates to construct fst applier"))]
147 EmptyPredicates {
148 #[snafu(implicit)]
149 location: Location,
150 },
151
152 #[snafu(display("Failed to construct intersection fst applier with InList predicate"))]
153 IntersectionApplierWithInList {
154 #[snafu(implicit)]
155 location: Location,
156 },
157
158 #[snafu(display("Failed to construct keys fst applier without InList predicate"))]
159 KeysApplierWithoutInList {
160 #[snafu(implicit)]
161 location: Location,
162 },
163
164 #[snafu(display(
165 "Failed to construct keys fst applier with unexpected predicates: {predicates:?}"
166 ))]
167 KeysApplierUnexpectedPredicates {
168 #[snafu(implicit)]
169 location: Location,
170 predicates: Vec<Predicate>,
171 },
172
173 #[snafu(display("index not found, name: {name}"))]
174 IndexNotFound {
175 name: String,
176 #[snafu(implicit)]
177 location: Location,
178 },
179
180 #[snafu(display("Failed to insert value to FST"))]
181 FstInsert {
182 #[snafu(source)]
183 error: fst::Error,
184 #[snafu(implicit)]
185 location: Location,
186 },
187
188 #[snafu(display("Failed to compile FST"))]
189 FstCompile {
190 #[snafu(source)]
191 error: fst::Error,
192 #[snafu(implicit)]
193 location: Location,
194 },
195
196 #[snafu(display("Failed to perform IO operation"))]
197 CommonIo {
198 #[snafu(source)]
199 error: IoError,
200 #[snafu(implicit)]
201 location: Location,
202 },
203
204 #[snafu(display("Unknown intermediate codec magic: {magic:?}"))]
205 UnknownIntermediateCodecMagic {
206 magic: [u8; 4],
207 #[snafu(implicit)]
208 location: Location,
209 },
210
211 #[snafu(display("Inconsistent row count, index_name: {index_name}, total_row_count: {total_row_count}, expected: {expected_row_count}"))]
212 InconsistentRowCount {
213 index_name: String,
214 total_row_count: usize,
215 expected_row_count: usize,
216 },
217
218 #[snafu(display("External error"))]
219 External {
220 source: BoxedError,
221 #[snafu(implicit)]
222 location: Location,
223 },
224
225 #[snafu(display("Intermediate error"))]
226 Intermediate {
227 source: crate::error::Error,
228 #[snafu(implicit)]
229 location: Location,
230 },
231}
232
233impl ErrorExt for Error {
234 fn status_code(&self) -> StatusCode {
235 use Error::*;
236 match self {
237 Read { .. }
238 | Write { .. }
239 | Flush { .. }
240 | Close { .. }
241 | UnexpectedFooterPayloadSize { .. }
242 | UnexpectedZeroSegmentRowCount { .. }
243 | UnexpectedOffsetSize { .. }
244 | UnexpectedBlobSize { .. }
245 | DecodeProto { .. }
246 | DecodeFst { .. }
247 | KeysApplierUnexpectedPredicates { .. }
248 | CommonIo { .. }
249 | UnknownIntermediateCodecMagic { .. }
250 | FstCompile { .. }
251 | DecodeBitmap { .. }
252 | InvalidFooterPayloadSize { .. }
253 | BlobSizeTooSmall { .. } => StatusCode::Unexpected,
254
255 ParseRegex { .. }
256 | ParseDFA { .. }
257 | KeysApplierWithoutInList { .. }
258 | IntersectionApplierWithInList { .. }
259 | EmptyPredicates { .. }
260 | FstInsert { .. }
261 | InconsistentRowCount { .. }
262 | IndexNotFound { .. } => StatusCode::InvalidArguments,
263
264 Intermediate { source, .. } => source.status_code(),
265 External { source, .. } => source.status_code(),
266 }
267 }
268
269 fn as_any(&self) -> &dyn Any {
270 self
271 }
272}
273
274pub type Result<T> = std::result::Result<T, Error>;