use re_log_types::{ComponentPath, EntryId};
use re_protos::EntryName;
use re_protos::common::v1alpha1::ext::SegmentId;
#[derive(thiserror::Error, Debug)]
#[expect(clippy::enum_variant_names)]
pub enum Error {
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error(transparent)]
StoreLoadError(#[from] re_entity_db::StoreLoadError),
#[error("Invalid entry name: {0}")]
InvalidEntryName(#[from] re_protos::InvalidEntryNameError),
#[error("Entry name '{0}' already exists")]
DuplicateEntryNameError(EntryName),
#[error("Entry id '{0}' already exists")]
DuplicateEntryIdError(EntryId),
#[error("Entry name '{0}' not found")]
EntryNameNotFound(EntryName),
#[error("Entry id '{0}' not found")]
EntryIdNotFound(EntryId),
#[error("Segment '{segment_id}' not found in dataset '{entry_id}'")]
SegmentIdNotFound {
segment_id: SegmentId,
entry_id: EntryId,
},
#[error("Layer '{layer_name}' not found in segment '{segment_id}' of dataset '{entry_id}'")]
LayerNameNotFound {
layer_name: String,
segment_id: SegmentId,
entry_id: EntryId,
},
#[error("Layer '{0}' already exists")]
LayerAlreadyExists(String),
#[error("Component path '{0}' not found")]
ComponentPathNotFound(ComponentPath),
#[error("Index '{0}' already exists")]
IndexAlreadyExists(String),
#[error(transparent)]
DataFusionError(#[from] datafusion::error::DataFusionError),
#[error(transparent)]
ArrowError(#[from] arrow::error::ArrowError),
#[cfg(feature = "lance")]
#[error(transparent)]
LanceError(#[from] lance::Error),
#[error("Indexing error: {0}")]
IndexingError(String),
#[error("Error loading RRD: {0}")]
RrdLoadingError(anyhow::Error),
#[error("Failed to encode chunk key: {0}")]
FailedToEncodeChunkKey(String),
#[error("Failed to decode chunk key: {0}")]
FailedToDecodeChunkKey(String),
#[error("Invalid chunk key: {0}")]
InvalidChunkKey(String),
#[error("Failed to extract properties: {0:#?}")]
FailedToExtractProperties(String),
#[error("{0}")]
SchemaConflict(String),
#[error("Table storage already exists at location: {0}")]
TableStorageAlreadyExists(String),
}
impl Error {
#[inline]
pub fn failed_to_extract_properties(err: impl std::error::Error) -> Self {
Self::FailedToExtractProperties(err.to_string())
}
}
impl From<Error> for tonic::Status {
fn from(err: Error) -> Self {
match &err {
Error::IoError(err) => Self::internal(format!("IO error: {err:#}")),
Error::StoreLoadError(err) => Self::internal(format!("Store load error: {err:#}")),
Error::EntryIdNotFound(_)
| Error::EntryNameNotFound(_)
| Error::SegmentIdNotFound { .. }
| Error::LayerNameNotFound { .. }
| Error::ComponentPathNotFound(_)
| Error::InvalidChunkKey(_) => Self::not_found(format!("{err:#}")),
Error::DataFusionError(err) => Self::internal(format!("DataFusion error: {err:#}")),
Error::ArrowError(err) => Self::internal(format!("Arrow error: {err:#}")),
#[cfg(feature = "lance")]
Error::LanceError(err) => Self::internal(format!("Lance error: {err:#}")),
Error::RrdLoadingError(err) => Self::internal(format!("{err:#}")),
Error::FailedToDecodeChunkKey(_) => Self::invalid_argument(format!("{err:#}")),
Error::FailedToEncodeChunkKey(_) | Error::FailedToExtractProperties(_) => {
Self::internal(format!("{err:#}"))
}
Error::InvalidEntryName(_) => Self::invalid_argument(format!("{err:#}")),
Error::DuplicateEntryNameError(_)
| Error::DuplicateEntryIdError(_)
| Error::LayerAlreadyExists(_)
| Error::IndexAlreadyExists(_)
| Error::TableStorageAlreadyExists(_) => Self::already_exists(format!("{err:#}")),
Error::IndexingError(_) => Self::internal(format!("Indexing error: {err:#}")),
Error::SchemaConflict(_) => Self::invalid_argument(format!("{err:#}")),
}
}
}