use std::any::Any;
use std::io::Error as IoError;
use common_error::ext::{BoxedError, ErrorExt};
use common_error::status_code::StatusCode;
use common_macro::stack_trace_debug;
use snafu::{Location, Snafu};
use crate::inverted_index::search::predicate::Predicate;
#[derive(Snafu)]
#[snafu(visibility(pub))]
#[stack_trace_debug]
pub enum Error {
#[snafu(display("Failed to read"))]
Read {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to write"))]
Write {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to flush"))]
Flush {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to close"))]
Close {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display(
"Unexpected inverted index blob size, min: {min_blob_size}, actual: {actual_blob_size}"
))]
UnexpectedBlobSize {
min_blob_size: u64,
actual_blob_size: u64,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Blob size too small"))]
BlobSizeTooSmall {
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Invalid footer payload size"))]
InvalidFooterPayloadSize {
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Unexpected inverted index footer payload size, max: {max_payload_size}, actual: {actual_payload_size}"))]
UnexpectedFooterPayloadSize {
max_payload_size: u64,
actual_payload_size: u64,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Unexpected inverted index offset size, offset: {offset}, size: {size}, blob_size: {blob_size}, payload_size: {payload_size}"))]
UnexpectedOffsetSize {
offset: u64,
size: u64,
blob_size: u64,
payload_size: u64,
},
#[snafu(display("Unexpected zero segment row count"))]
UnexpectedZeroSegmentRowCount {
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to decode fst"))]
DecodeFst {
#[snafu(source)]
error: fst::Error,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to decode bitmap"))]
DecodeBitmap {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to decode protobuf"))]
DecodeProto {
#[snafu(source)]
error: prost::DecodeError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to parse regex pattern: {pattern}"))]
ParseRegex {
#[snafu(source)]
error: regex::Error,
pattern: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to parse regex DFA"))]
ParseDFA {
#[snafu(source)]
error: Box<regex_automata::dfa::dense::BuildError>,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Unexpected empty predicates to construct fst applier"))]
EmptyPredicates {
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to construct intersection fst applier with InList predicate"))]
IntersectionApplierWithInList {
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to construct keys fst applier without InList predicate"))]
KeysApplierWithoutInList {
#[snafu(implicit)]
location: Location,
},
#[snafu(display(
"Failed to construct keys fst applier with unexpected predicates: {predicates:?}"
))]
KeysApplierUnexpectedPredicates {
#[snafu(implicit)]
location: Location,
predicates: Vec<Predicate>,
},
#[snafu(display("index not found, name: {name}"))]
IndexNotFound {
name: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to insert value to FST"))]
FstInsert {
#[snafu(source)]
error: fst::Error,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to compile FST"))]
FstCompile {
#[snafu(source)]
error: fst::Error,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to perform IO operation"))]
CommonIo {
#[snafu(source)]
error: IoError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Unknown intermediate codec magic: {magic:?}"))]
UnknownIntermediateCodecMagic {
magic: [u8; 4],
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Inconsistent row count, index_name: {index_name}, total_row_count: {total_row_count}, expected: {expected_row_count}"))]
InconsistentRowCount {
index_name: String,
total_row_count: usize,
expected_row_count: usize,
},
#[snafu(display("External error"))]
External {
source: BoxedError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Intermediate error"))]
Intermediate {
source: crate::error::Error,
#[snafu(implicit)]
location: Location,
},
}
impl ErrorExt for Error {
fn status_code(&self) -> StatusCode {
use Error::*;
match self {
Read { .. }
| Write { .. }
| Flush { .. }
| Close { .. }
| UnexpectedFooterPayloadSize { .. }
| UnexpectedZeroSegmentRowCount { .. }
| UnexpectedOffsetSize { .. }
| UnexpectedBlobSize { .. }
| DecodeProto { .. }
| DecodeFst { .. }
| KeysApplierUnexpectedPredicates { .. }
| CommonIo { .. }
| UnknownIntermediateCodecMagic { .. }
| FstCompile { .. }
| DecodeBitmap { .. }
| InvalidFooterPayloadSize { .. }
| BlobSizeTooSmall { .. } => StatusCode::Unexpected,
ParseRegex { .. }
| ParseDFA { .. }
| KeysApplierWithoutInList { .. }
| IntersectionApplierWithInList { .. }
| EmptyPredicates { .. }
| FstInsert { .. }
| InconsistentRowCount { .. }
| IndexNotFound { .. } => StatusCode::InvalidArguments,
Intermediate { source, .. } => source.status_code(),
External { source, .. } => source.status_code(),
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
pub type Result<T> = std::result::Result<T, Error>;