use snafu::prelude::*;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(whatever, display("Paimon data invalid for {}: {:?}", message, source))]
DataInvalid {
message: String,
#[snafu(source(from(Box<dyn std::error::Error + Send + Sync + 'static>, Some)))]
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
},
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unsupported error {}", message)
)]
Unsupported { message: String },
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unexpected error {}: {:?}", message, source)
)]
UnexpectedError {
message: String,
#[snafu(source(false))]
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
},
#[snafu(
visibility(pub(crate)),
display("Paimon data type invalid for {}", message)
)]
DataTypeInvalid { message: String },
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unexpected error {}: {:?}", message, source)
)]
IoUnexpected {
message: String,
#[snafu(source(from(opendal::Error, Box::new)))]
source: Box<opendal::Error>,
},
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unsupported io error {}", message)
)]
IoUnsupported { message: String },
#[snafu(
visibility(pub(crate)),
display("Paimon hitting invalid config: {}", message)
)]
ConfigInvalid { message: String },
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unexpected avro error {}: {:?}", message, source)
)]
DataUnexpected {
message: String,
source: Box<apache_avro::Error>,
},
#[snafu(
visibility(pub(crate)),
display("Paimon hitting invalid file index format: {}", message)
)]
FileIndexFormatInvalid { message: String },
#[snafu(
visibility(pub(crate)),
display("Paimon hitting unexpected parquet error: {}", message)
)]
ParquetDataUnexpected {
message: String,
source: Box<parquet::errors::ParquetError>,
},
#[snafu(display("Database {} already exists.", database))]
DatabaseAlreadyExist { database: String },
#[snafu(display("Database {} does not exist.", database))]
DatabaseNotExist { database: String },
#[snafu(display("Database {} is not empty.", database))]
DatabaseNotEmpty { database: String },
#[snafu(display("Table {} already exists.", full_name))]
TableAlreadyExist { full_name: String },
#[snafu(display("Table {} does not exist.", full_name))]
TableNotExist { full_name: String },
#[snafu(display("Column {} already exists in table {}.", column, full_name))]
ColumnAlreadyExist { full_name: String, column: String },
#[snafu(display("Column {} does not exist in table {}.", column, full_name))]
ColumnNotExist { full_name: String, column: String },
#[snafu(display("Invalid identifier: {}", message))]
IdentifierInvalid { message: String },
#[snafu(display("{}", source))]
RestApi {
#[snafu(source)]
source: crate::api::rest_error::RestError,
},
}
impl From<opendal::Error> for Error {
fn from(source: opendal::Error) -> Self {
Error::IoUnexpected {
message: "IO operation failed on underlying storage".to_string(),
source: Box::new(source),
}
}
}
impl From<apache_avro::Error> for Error {
fn from(source: apache_avro::Error) -> Self {
Error::DataUnexpected {
message: "Failed to process Avro data".to_string(),
source: Box::new(source),
}
}
}
impl From<parquet::errors::ParquetError> for Error {
fn from(source: parquet::errors::ParquetError) -> Self {
Error::ParquetDataUnexpected {
message: format!("Failed to read a Parquet file: {source}"),
source: Box::new(source),
}
}
}
impl From<crate::api::rest_error::RestError> for Error {
fn from(source: crate::api::rest_error::RestError) -> Self {
Error::RestApi { source }
}
}