use std::sync::Arc;
use arrow::error::ArrowError;
use nd_arrow_array::NdError;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error(transparent)]
Nd(#[from] NdError),
#[error(transparent)]
Lance(Box<lance::Error>),
#[error(transparent)]
Arrow(#[from] ArrowError),
#[error("schema mismatch: {0}")]
SchemaMismatch(String),
#[error("invalid table: {0}")]
InvalidTable(String),
#[error("invalid argument: {0}")]
InvalidArgument(String),
#[error("no table at {0}")]
TableNotFound(String),
#[error("a table exists at {0}")]
TableExists(String),
#[error("commit conflict: {source}")]
CommitConflict {
retryable: bool,
source: Box<lance::Error>,
},
#[error("the writer failed, nothing is committed: {0}")]
WriterFailed(#[source] Arc<Error>),
#[error("a fragment write stopped: {0}")]
TaskFailed(#[from] tokio::task::JoinError),
}
impl From<lance::Error> for Error {
fn from(error: lance::Error) -> Self {
match error {
lance::Error::DatasetNotFound { path, .. } => Self::TableNotFound(path),
lance::Error::DatasetAlreadyExists { uri, .. } => Self::TableExists(uri),
lance::Error::CommitConflict { .. }
| lance::Error::RetryableCommitConflict { .. }
| lance::Error::TooMuchWriteContention { .. } => Self::CommitConflict {
retryable: true,
source: Box::new(error),
},
lance::Error::IncompatibleTransaction { .. } => Self::CommitConflict {
retryable: false,
source: Box::new(error),
},
error => Self::Lance(Box::new(error)),
}
}
}
pub type Result<T, E = Error> = std::result::Result<T, E>;