diff --git a/lib/src/default_index/readonly.rs b/lib/src/default_index/readonly.rs index 8a88ee435e..e7a43a9377 100644 --- a/lib/src/default_index/readonly.rs +++ b/lib/src/default_index/readonly.rs @@ -37,13 +37,20 @@ use crate::store::Store; /// Error while loading index segment file. #[derive(Debug, Error)] -#[error("Failed to load commit index file '{name}'")] -pub struct ReadonlyIndexLoadError { - /// Index file name. - pub name: String, - /// Underlying error. - #[source] - pub error: io::Error, +pub enum ReadonlyIndexLoadError { + #[error("Unexpected index version")] + UnexpectedVersion { + found_version: u32, + expected_version: u32, + }, + #[error("Failed to load commit index file '{name}'")] + Other { + /// Index file name. + name: String, + /// Underlying error. + #[source] + error: io::Error, + }, } impl ReadonlyIndexLoadError { @@ -55,7 +62,7 @@ impl ReadonlyIndexLoadError { } fn from_io_err(name: impl Into, error: io::Error) -> Self { - ReadonlyIndexLoadError { + ReadonlyIndexLoadError::Other { name: name.into(), error, } @@ -63,12 +70,19 @@ impl ReadonlyIndexLoadError { /// Returns true if the underlying error suggests data corruption. pub(super) fn is_corrupt_or_not_found(&self) -> bool { - // If the parent file name field is corrupt, the file wouldn't be found. - // And there's no need to distinguish it from an empty file. - matches!( - self.error.kind(), - io::ErrorKind::NotFound | io::ErrorKind::InvalidData | io::ErrorKind::UnexpectedEof - ) + match self { + ReadonlyIndexLoadError::UnexpectedVersion { .. } => true, + ReadonlyIndexLoadError::Other { name: _, error } => { + // If the parent file name field is corrupt, the file wouldn't be found. + // And there's no need to distinguish it from an empty file. + matches!( + error.kind(), + io::ErrorKind::NotFound + | io::ErrorKind::InvalidData + | io::ErrorKind::UnexpectedEof + ) + } + } } } @@ -244,10 +258,10 @@ impl ReadonlyIndexSegment { }; let format_version = read_u32(file)?; if format_version != INDEX_SEGMENT_FILE_FORMAT_VERSION { - return Err(ReadonlyIndexLoadError::invalid_data( - &name, - format!("unsupported file format version: {format_version}"), - )); + return Err(ReadonlyIndexLoadError::UnexpectedVersion { + found_version: format_version, + expected_version: INDEX_SEGMENT_FILE_FORMAT_VERSION, + }); } let parent_filename_len = read_u32(file)?; let maybe_parent_file = if parent_filename_len > 0 { diff --git a/lib/src/default_index/store.rs b/lib/src/default_index/store.rs index ad388a84a9..a751ef9bff 100644 --- a/lib/src/default_index/store.rs +++ b/lib/src/default_index/store.rs @@ -330,11 +330,23 @@ impl IndexStore for DefaultIndexStore { Err(DefaultIndexStoreError::LoadIndex(err)) if err.is_corrupt_or_not_found() => { // If the index was corrupt (maybe it was written in a different format), // we just reindex. - // TODO: Move this message to a callback or something. - eprintln!( - "{err} (maybe the format has changed): {source}. Reindexing...", - source = err.error - ); + match &err { + ReadonlyIndexLoadError::UnexpectedVersion { + found_version, + expected_version, + } => { + eprintln!( + "Found index format version {found_version}, expected version \ + {expected_version}. Reindexing..." + ); + } + ReadonlyIndexLoadError::Other { name: _, error } => { + eprintln!( + "{err} (maybe the format has changed): {source}. Reindexing...", + source = error + ); + } + } self.reinit().map_err(|err| IndexReadError(err.into()))?; self.build_index_segments_at_operation(op, store) }