use std::any::Any;
use common_error::ext::ErrorExt;
use common_error::status_code::StatusCode;
use common_macro::stack_trace_debug;
use datafusion::arrow::error::ArrowError;
use datafusion::error::DataFusionError;
use serde_json::error::Error as JsonError;
use snafu::{Location, Snafu};
use store_api::storage::RegionId;
#[derive(Snafu)]
#[snafu(visibility(pub))]
#[stack_trace_debug]
pub enum Error {
#[snafu(display("Unsupported operation: {}", operation))]
Unsupported {
operation: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Unexpected engine: {}", engine))]
UnexpectedEngine {
engine: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Invalid region metadata"))]
InvalidMetadata {
source: store_api::metadata::MetadataError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Region not found, region_id: {}", region_id))]
RegionNotFound {
region_id: RegionId,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to check object from path: {}", path))]
CheckObject {
path: String,
#[snafu(implicit)]
location: Location,
#[snafu(source)]
error: object_store::Error,
},
#[snafu(display("Fail to encode object into json"))]
EncodeJson {
#[snafu(implicit)]
location: Location,
#[snafu(source)]
error: JsonError,
},
#[snafu(display("Fail to decode object from json"))]
DecodeJson {
#[snafu(implicit)]
location: Location,
#[snafu(source)]
error: JsonError,
},
#[snafu(display("Failed to store region manifest, region_id: {}", region_id))]
StoreRegionManifest {
#[snafu(source)]
error: object_store::Error,
region_id: RegionId,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to load region manifest, region_id: {}", region_id))]
LoadRegionManifest {
#[snafu(source)]
error: object_store::Error,
region_id: RegionId,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to delete region manifest, region_id: {},", region_id))]
DeleteRegionManifest {
#[snafu(source)]
error: object_store::Error,
region_id: RegionId,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Manifest already exists: {}", path))]
ManifestExists {
path: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Missing required field: {}", name))]
MissingRequiredField {
name: String,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to build backend"))]
BuildBackend {
#[snafu(implicit)]
location: Location,
source: common_datasource::error::Error,
},
#[snafu(display("Failed to build csv config"))]
BuildCsvConfig {
#[snafu(source)]
error: common_datasource::file_format::csv::CsvConfigBuilderError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to build stream"))]
BuildStream {
#[snafu(source)]
error: DataFusionError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to project schema"))]
ProjectArrowSchema {
#[snafu(source)]
error: ArrowError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to project schema"))]
ProjectSchema {
source: datatypes::error::Error,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to build stream adapter"))]
BuildStreamAdapter {
#[snafu(implicit)]
location: Location,
source: common_recordbatch::error::Error,
},
#[snafu(display("Failed to parse file format"))]
ParseFileFormat {
#[snafu(implicit)]
location: Location,
source: common_datasource::error::Error,
},
#[snafu(display("Failed to generate parquet scan plan"))]
ParquetScanPlan {
#[snafu(source)]
error: DataFusionError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display(
"Projection out of bounds, column_index: {}, bounds: {}",
column_index,
bounds
))]
ProjectionOutOfBounds {
column_index: usize,
bounds: usize,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to extract column from filter"))]
ExtractColumnFromFilter {
#[snafu(source)]
error: DataFusionError,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Failed to create default value for column: {}", column))]
CreateDefault {
column: String,
source: datatypes::error::Error,
#[snafu(implicit)]
location: Location,
},
#[snafu(display("Missing default value for column: {}", column))]
MissingColumnNoDefault {
column: String,
#[snafu(implicit)]
location: Location,
},
}
pub type Result<T> = std::result::Result<T, Error>;
impl ErrorExt for Error {
fn status_code(&self) -> StatusCode {
use Error::*;
match self {
BuildCsvConfig { .. }
| ProjectArrowSchema { .. }
| ProjectSchema { .. }
| MissingRequiredField { .. }
| Unsupported { .. }
| InvalidMetadata { .. }
| ProjectionOutOfBounds { .. }
| CreateDefault { .. }
| MissingColumnNoDefault { .. } => StatusCode::InvalidArguments,
RegionNotFound { .. } => StatusCode::RegionNotFound,
BuildBackend { source, .. } => source.status_code(),
BuildStreamAdapter { source, .. } => source.status_code(),
ParseFileFormat { source, .. } => source.status_code(),
CheckObject { .. }
| StoreRegionManifest { .. }
| LoadRegionManifest { .. }
| DeleteRegionManifest { .. } => StatusCode::StorageUnavailable,
EncodeJson { .. }
| DecodeJson { .. }
| ManifestExists { .. }
| BuildStream { .. }
| ParquetScanPlan { .. }
| UnexpectedEngine { .. }
| ExtractColumnFromFilter { .. } => StatusCode::Unexpected,
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl From<Error> for common_procedure::Error {
fn from(e: Error) -> common_procedure::Error {
common_procedure::Error::from_error_ext(e)
}
}