use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Error {
Configuration,
InvalidRunOptions {
field: &'static str,
},
RunAlreadyExists {
run_id: String,
},
RunAlreadyActive {
run_id: String,
},
RunNotFound {
run_id: String,
},
DuplicateRunIdentity {
run_id: String,
},
InvalidRunState {
run_id: String,
},
RunProjectMismatch {
run_id: String,
},
InvalidMetricMapping,
MetricMappingTooLarge {
count: usize,
maximum: usize,
},
MetricQueueFull,
RunClosed {
run_id: String,
},
StepRegression {
cursor: i64,
attempted: i64,
},
StepOverflow {
step: i64,
},
TerminalOutcomeConflict {
selected: crate::RunStatus,
requested: crate::RunStatus,
},
MetricWriterFailed,
MetricDrainTimeout,
MetricFlushFailed,
MetricFlushTimeout,
ClientClosed,
UnsupportedQuery,
CatalogNotFound {
name: String,
},
LttbExtensionUnavailable {
message: String,
},
Storage,
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Configuration => formatter.write_str("Seex configuration is invalid"),
Self::InvalidRunOptions { field } => {
write!(formatter, "Seex Run option `{field}` is invalid")
}
Self::RunAlreadyExists { run_id } => write!(formatter, "Run already exists: {run_id}"),
Self::RunAlreadyActive { run_id } => {
write!(formatter, "Run already has an active writer: {run_id}")
}
Self::RunNotFound { run_id } => write!(formatter, "Run not found: {run_id}"),
Self::DuplicateRunIdentity { run_id } => {
write!(formatter, "duplicate Run identity in request: {run_id}")
}
Self::InvalidRunState { run_id } => {
write!(
formatter,
"Run state does not allow this operation: {run_id}"
)
}
Self::RunProjectMismatch { run_id } => {
write!(formatter, "Run belongs to a different Project: {run_id}")
}
Self::InvalidMetricMapping => formatter.write_str("metric Mapping is invalid"),
Self::MetricMappingTooLarge { count, maximum } => {
write!(
formatter,
"metric Mapping has {count} points; maximum is {maximum}"
)
}
Self::MetricQueueFull => formatter.write_str("Seex metric queue is full"),
Self::RunClosed { run_id } => write!(formatter, "Run is closed: {run_id}"),
Self::StepRegression { cursor, attempted } => write!(
formatter,
"committed step {attempted} regresses from cursor {cursor}"
),
Self::StepOverflow { step } => {
write!(formatter, "step {step} has no representable successor")
}
Self::TerminalOutcomeConflict {
selected,
requested,
} => write!(
formatter,
"Run terminal outcome conflicts: selected {selected:?}, requested {requested:?}"
),
Self::MetricWriterFailed => formatter.write_str("Seex metric writer failed"),
Self::MetricDrainTimeout => formatter.write_str("Seex metric drain timed out"),
Self::MetricFlushFailed => formatter.write_str("Seex metric flush failed"),
Self::MetricFlushTimeout => formatter.write_str("Seex metric flush timed out"),
Self::ClientClosed => formatter.write_str("Seex client is closed"),
Self::UnsupportedQuery => formatter.write_str("Reader query is not yet supported"),
Self::CatalogNotFound { name } => write!(formatter, "catalog not found: {name}"),
Self::LttbExtensionUnavailable { message } => {
write!(formatter, "DuckDB LTTB extension is unavailable: {message}")
}
Self::Storage => formatter.write_str("Seex storage operation failed"),
}
}
}
impl std::error::Error for Error {}
impl From<crate::engine::EngineError> for Error {
fn from(error: crate::engine::EngineError) -> Self {
use crate::engine::EngineError;
match error {
EngineError::RunAlreadyExists { run_id } => Self::RunAlreadyExists { run_id },
EngineError::RunAlreadyActive { run_id } => Self::RunAlreadyActive { run_id },
EngineError::RunNotFound { run_id } => Self::RunNotFound { run_id },
EngineError::DuplicateRunIdentity { run_id } => Self::DuplicateRunIdentity { run_id },
EngineError::InvalidRunTransition { run_id, .. } => Self::InvalidRunState { run_id },
EngineError::MetricQueueFull => Self::MetricQueueFull,
EngineError::InvalidMetricBatch { count } => Self::MetricMappingTooLarge {
count,
maximum: 8_192,
},
EngineError::RunClosed { run_id } => Self::RunClosed { run_id },
EngineError::StepRegression { cursor, attempted } => {
Self::StepRegression { cursor, attempted }
}
EngineError::StepOverflow { step } => Self::StepOverflow { step },
EngineError::MetricWriterFailed { .. } => Self::MetricWriterFailed,
EngineError::MetricDrainTimeout => Self::MetricDrainTimeout,
EngineError::MetricFlush { .. } => Self::MetricFlushFailed,
EngineError::MetricFlushTimeout => Self::MetricFlushTimeout,
EngineError::ClientClosed => Self::ClientClosed,
EngineError::StorageFailure(crate::storage::StorageError::CatalogNotFound { name }) => {
Self::CatalogNotFound { name }
}
EngineError::StorageFailure(
crate::storage::StorageError::LttbExtensionUnavailable { message },
) => Self::LttbExtensionUnavailable { message },
_ => Self::Storage,
}
}
}