Skip to content

Commit

Permalink
make errors cloneable
Browse files Browse the repository at this point in the history
  • Loading branch information
PSeitz committed Jun 30, 2022
1 parent db18366 commit 7eb2673
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 33 deletions.
10 changes: 8 additions & 2 deletions src/directory/directory.rs
@@ -1,6 +1,7 @@
use std::io::Write;
use std::marker::{Send, Sync};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
use std::{fmt, io, thread};

Expand Down Expand Up @@ -62,7 +63,12 @@ impl Drop for DirectoryLockGuard {

enum TryAcquireLockError {
FileExists,
IoError(io::Error),
IoError(Arc<io::Error>),
}
impl From<io::Error> for TryAcquireLockError {
fn from(io_error: io::Error) -> Self {
Self::IoError(Arc::new(io_error))
}
}

fn try_acquire_lock(
Expand All @@ -73,7 +79,7 @@ fn try_acquire_lock(
OpenWriteError::FileAlreadyExists(_) => TryAcquireLockError::FileExists,
OpenWriteError::IoError { io_error, .. } => TryAcquireLockError::IoError(io_error),
})?;
write.flush().map_err(TryAcquireLockError::IoError)?;
write.flush().map_err(TryAcquireLockError::from)?;
Ok(DirectoryLock::from(Box::new(DirectoryLockGuard {
directory: directory.box_clone(),
path: filepath.to_owned(),
Expand Down
43 changes: 29 additions & 14 deletions src/directory/error.rs
@@ -1,10 +1,11 @@
use std::path::PathBuf;
use std::sync::Arc;
use std::{fmt, io};

use crate::Version;

/// Error while trying to acquire a directory lock.
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum LockError {
/// Failed to acquired a lock as it is already held by another
/// client.
Expand All @@ -16,11 +17,18 @@ pub enum LockError {
LockBusy,
/// Trying to acquire a lock failed with an `IoError`
#[error("Failed to acquire the lock due to an io:Error.")]
IoError(io::Error),
IoError(Arc<io::Error>),
}

impl LockError {
/// Wraps an io error.
pub fn wrap_io_error(io_error: io::Error) -> Self {
Self::IoError(Arc::new(io_error))
}
}

/// Error that may occur when opening a directory
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum OpenDirectoryError {
/// The underlying directory does not exists.
#[error("Directory does not exist: '{0}'.")]
Expand All @@ -30,12 +38,12 @@ pub enum OpenDirectoryError {
NotADirectory(PathBuf),
/// Failed to create a temp directory.
#[error("Failed to create a temporary directory: '{0}'.")]
FailedToCreateTempDir(io::Error),
FailedToCreateTempDir(Arc<io::Error>),
/// IoError
#[error("IoError '{io_error:?}' while create directory in: '{directory_path:?}'.")]
IoError {
/// underlying io Error.
io_error: io::Error,
io_error: Arc<io::Error>,
/// directory we tried to open.
directory_path: PathBuf,
},
Expand All @@ -45,14 +53,14 @@ impl OpenDirectoryError {
/// Wraps an io error.
pub fn wrap_io_error(io_error: io::Error, directory_path: PathBuf) -> Self {
Self::IoError {
io_error,
io_error: Arc::new(io_error),
directory_path,
}
}
}

/// Error that may occur when starting to write in a file
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum OpenWriteError {
/// Our directory is WORM, writing an existing file is forbidden.
/// Checkout the `Directory` documentation.
Expand All @@ -63,7 +71,7 @@ pub enum OpenWriteError {
#[error("IoError '{io_error:?}' while opening file for write: '{filepath}'.")]
IoError {
/// The underlying `io::Error`.
io_error: io::Error,
io_error: Arc<io::Error>,
/// File path of the file that tantivy failed to open for write.
filepath: PathBuf,
},
Expand All @@ -72,11 +80,15 @@ pub enum OpenWriteError {
impl OpenWriteError {
/// Wraps an io error.
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
Self::IoError { io_error, filepath }
Self::IoError {
io_error: Arc::new(io_error),
filepath,
}
}
}
/// Type of index incompatibility between the library and the index found on disk
/// Used to catch and provide a hint to solve this incompatibility issue
#[derive(Clone)]
pub enum Incompatibility {
/// This library cannot decompress the index found on disk
CompressionMismatch {
Expand Down Expand Up @@ -135,7 +147,7 @@ impl fmt::Debug for Incompatibility {
}

/// Error that may occur when accessing a file read
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum OpenReadError {
/// The file does not exists.
#[error("Files does not exists: {0:?}")]
Expand All @@ -146,7 +158,7 @@ pub enum OpenReadError {
)]
IoError {
/// The underlying `io::Error`.
io_error: io::Error,
io_error: Arc<io::Error>,
/// File path of the file that tantivy failed to open for read.
filepath: PathBuf,
},
Expand All @@ -158,11 +170,14 @@ pub enum OpenReadError {
impl OpenReadError {
/// Wraps an io error.
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
Self::IoError { io_error, filepath }
Self::IoError {
io_error: Arc::new(io_error),
filepath,
}
}
}
/// Error that may occur when trying to delete a file
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum DeleteError {
/// The file does not exists.
#[error("File does not exists: '{0}'.")]
Expand All @@ -172,7 +187,7 @@ pub enum DeleteError {
#[error("The following IO error happened while deleting file '{filepath}': '{io_error:?}'.")]
IoError {
/// The underlying `io::Error`.
io_error: io::Error,
io_error: Arc<io::Error>,
/// File path of the file that tantivy failed to delete.
filepath: PathBuf,
},
Expand Down
9 changes: 3 additions & 6 deletions src/directory/managed_directory.rs
Expand Up @@ -242,16 +242,13 @@ impl ManagedDirectory {
/// Verify checksum of a managed file
pub fn validate_checksum(&self, path: &Path) -> result::Result<bool, OpenReadError> {
let reader = self.directory.open_read(path)?;
let (footer, data) =
Footer::extract_footer(reader).map_err(|io_error| OpenReadError::IoError {
io_error,
filepath: path.to_path_buf(),
})?;
let (footer, data) = Footer::extract_footer(reader)
.map_err(|io_error| OpenReadError::wrap_io_error(io_error, path.to_path_buf()))?;
let bytes = data
.read_bytes()
.map_err(|io_error| OpenReadError::IoError {
io_error: Arc::new(io_error),
filepath: path.to_path_buf(),
io_error,
})?;
let mut hasher = Hasher::new();
hasher.update(bytes.as_slice());
Expand Down
9 changes: 5 additions & 4 deletions src/directory/mmap_directory.rs
Expand Up @@ -174,7 +174,8 @@ impl MmapDirectory {
/// This is mostly useful to test the MmapDirectory itself.
/// For your unit tests, prefer the RamDirectory.
pub fn create_from_tempdir() -> Result<MmapDirectory, OpenDirectoryError> {
let tempdir = TempDir::new().map_err(OpenDirectoryError::FailedToCreateTempDir)?;
let tempdir = TempDir::new()
.map_err(|io_err| OpenDirectoryError::FailedToCreateTempDir(Arc::new(io_err)))?;
Ok(MmapDirectory::new(
tempdir.path().to_path_buf(),
Some(tempdir),
Expand Down Expand Up @@ -342,7 +343,7 @@ impl Directory for MmapDirectory {
DeleteError::FileDoesNotExist(path.to_owned())
} else {
DeleteError::IoError {
io_error: e,
io_error: Arc::new(e),
filepath: path.to_path_buf(),
}
}
Expand Down Expand Up @@ -422,9 +423,9 @@ impl Directory for MmapDirectory {
.write(true)
.create(true) //< if the file does not exist yet, create it.
.open(&full_path)
.map_err(LockError::IoError)?;
.map_err(LockError::wrap_io_error)?;
if lock.is_blocking {
file.lock_exclusive().map_err(LockError::IoError)?;
file.lock_exclusive().map_err(LockError::wrap_io_error)?;
} else {
file.try_lock_exclusive().map_err(|_| LockError::LockBusy)?
}
Expand Down
6 changes: 3 additions & 3 deletions src/directory/ram_directory.rs
Expand Up @@ -172,7 +172,7 @@ impl Directory for RamDirectory {
fn delete(&self, path: &Path) -> result::Result<(), DeleteError> {
fail_point!("RamDirectory::delete", |_| {
Err(DeleteError::IoError {
io_error: io::Error::from(io::ErrorKind::Other),
io_error: Arc::new(io::Error::from(io::ErrorKind::Other)),
filepath: path.to_path_buf(),
})
});
Expand All @@ -184,7 +184,7 @@ impl Directory for RamDirectory {
.fs
.read()
.map_err(|e| OpenReadError::IoError {
io_error: io::Error::new(io::ErrorKind::Other, e.to_string()),
io_error: Arc::new(io::Error::new(io::ErrorKind::Other, e.to_string())),
filepath: path.to_path_buf(),
})?
.exists(path))
Expand All @@ -208,7 +208,7 @@ impl Directory for RamDirectory {
self.open_read(path)?
.read_bytes()
.map_err(|io_error| OpenReadError::IoError {
io_error,
io_error: Arc::new(io_error),
filepath: path.to_path_buf(),
})?;
Ok(bytes.as_slice().to_owned())
Expand Down
14 changes: 10 additions & 4 deletions src/error.rs
@@ -1,7 +1,7 @@
//! Definition of Tantivy's errors and results.

use std::path::PathBuf;
use std::sync::PoisonError;
use std::sync::{Arc, PoisonError};
use std::{fmt, io};

use thiserror::Error;
Expand All @@ -15,6 +15,7 @@ use crate::{query, schema};
/// Represents a `DataCorruption` error.
///
/// When facing data corruption, tantivy actually panics or returns this error.
#[derive(Clone)]
pub struct DataCorruption {
filepath: Option<PathBuf>,
comment: String,
Expand Down Expand Up @@ -50,7 +51,7 @@ impl fmt::Debug for DataCorruption {
}

/// The library's error enum
#[derive(Debug, Error)]
#[derive(Debug, Clone, Error)]
pub enum TantivyError {
/// Failed to open the directory.
#[error("Failed to open the directory: '{0:?}'")]
Expand All @@ -69,7 +70,7 @@ pub enum TantivyError {
LockFailure(LockError, Option<String>),
/// IO Error.
#[error("An IO error occurred: '{0}'")]
IoError(#[from] io::Error),
IoError(Arc<io::Error>),
/// Data corruption.
#[error("Data corrupted: '{0:?}'")]
DataCorruption(DataCorruption),
Expand Down Expand Up @@ -125,6 +126,11 @@ impl From<AsyncIoError> for TantivyError {
}
}

impl From<io::Error> for TantivyError {
fn from(io_err: io::Error) -> TantivyError {
TantivyError::IoError(Arc::new(io_err))
}
}
impl From<DataCorruption> for TantivyError {
fn from(data_corruption: DataCorruption) -> TantivyError {
TantivyError::DataCorruption(data_corruption)
Expand Down Expand Up @@ -179,7 +185,7 @@ impl From<schema::DocParsingError> for TantivyError {

impl From<serde_json::Error> for TantivyError {
fn from(error: serde_json::Error) -> TantivyError {
TantivyError::IoError(error.into())
TantivyError::IoError(Arc::new(error.into()))
}
}

Expand Down

0 comments on commit 7eb2673

Please sign in to comment.