Skip to content

Commit 7eb2673

Browse files
committed
make errors cloneable
1 parent db18366 commit 7eb2673

File tree

6 files changed

+58
-33
lines changed

6 files changed

+58
-33
lines changed

src/directory/directory.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::io::Write;
22
use std::marker::{Send, Sync};
33
use std::path::{Path, PathBuf};
4+
use std::sync::Arc;
45
use std::time::Duration;
56
use std::{fmt, io, thread};
67

@@ -62,7 +63,12 @@ impl Drop for DirectoryLockGuard {
6263

6364
enum TryAcquireLockError {
6465
FileExists,
65-
IoError(io::Error),
66+
IoError(Arc<io::Error>),
67+
}
68+
impl From<io::Error> for TryAcquireLockError {
69+
fn from(io_error: io::Error) -> Self {
70+
Self::IoError(Arc::new(io_error))
71+
}
6672
}
6773

6874
fn try_acquire_lock(
@@ -73,7 +79,7 @@ fn try_acquire_lock(
7379
OpenWriteError::FileAlreadyExists(_) => TryAcquireLockError::FileExists,
7480
OpenWriteError::IoError { io_error, .. } => TryAcquireLockError::IoError(io_error),
7581
})?;
76-
write.flush().map_err(TryAcquireLockError::IoError)?;
82+
write.flush().map_err(TryAcquireLockError::from)?;
7783
Ok(DirectoryLock::from(Box::new(DirectoryLockGuard {
7884
directory: directory.box_clone(),
7985
path: filepath.to_owned(),

src/directory/error.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::path::PathBuf;
2+
use std::sync::Arc;
23
use std::{fmt, io};
34

45
use crate::Version;
56

67
/// Error while trying to acquire a directory lock.
7-
#[derive(Debug, Error)]
8+
#[derive(Debug, Clone, Error)]
89
pub enum LockError {
910
/// Failed to acquired a lock as it is already held by another
1011
/// client.
@@ -16,11 +17,18 @@ pub enum LockError {
1617
LockBusy,
1718
/// Trying to acquire a lock failed with an `IoError`
1819
#[error("Failed to acquire the lock due to an io:Error.")]
19-
IoError(io::Error),
20+
IoError(Arc<io::Error>),
21+
}
22+
23+
impl LockError {
24+
/// Wraps an io error.
25+
pub fn wrap_io_error(io_error: io::Error) -> Self {
26+
Self::IoError(Arc::new(io_error))
27+
}
2028
}
2129

2230
/// Error that may occur when opening a directory
23-
#[derive(Debug, Error)]
31+
#[derive(Debug, Clone, Error)]
2432
pub enum OpenDirectoryError {
2533
/// The underlying directory does not exists.
2634
#[error("Directory does not exist: '{0}'.")]
@@ -30,12 +38,12 @@ pub enum OpenDirectoryError {
3038
NotADirectory(PathBuf),
3139
/// Failed to create a temp directory.
3240
#[error("Failed to create a temporary directory: '{0}'.")]
33-
FailedToCreateTempDir(io::Error),
41+
FailedToCreateTempDir(Arc<io::Error>),
3442
/// IoError
3543
#[error("IoError '{io_error:?}' while create directory in: '{directory_path:?}'.")]
3644
IoError {
3745
/// underlying io Error.
38-
io_error: io::Error,
46+
io_error: Arc<io::Error>,
3947
/// directory we tried to open.
4048
directory_path: PathBuf,
4149
},
@@ -45,14 +53,14 @@ impl OpenDirectoryError {
4553
/// Wraps an io error.
4654
pub fn wrap_io_error(io_error: io::Error, directory_path: PathBuf) -> Self {
4755
Self::IoError {
48-
io_error,
56+
io_error: Arc::new(io_error),
4957
directory_path,
5058
}
5159
}
5260
}
5361

5462
/// Error that may occur when starting to write in a file
55-
#[derive(Debug, Error)]
63+
#[derive(Debug, Clone, Error)]
5664
pub enum OpenWriteError {
5765
/// Our directory is WORM, writing an existing file is forbidden.
5866
/// Checkout the `Directory` documentation.
@@ -63,7 +71,7 @@ pub enum OpenWriteError {
6371
#[error("IoError '{io_error:?}' while opening file for write: '{filepath}'.")]
6472
IoError {
6573
/// The underlying `io::Error`.
66-
io_error: io::Error,
74+
io_error: Arc<io::Error>,
6775
/// File path of the file that tantivy failed to open for write.
6876
filepath: PathBuf,
6977
},
@@ -72,11 +80,15 @@ pub enum OpenWriteError {
7280
impl OpenWriteError {
7381
/// Wraps an io error.
7482
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
75-
Self::IoError { io_error, filepath }
83+
Self::IoError {
84+
io_error: Arc::new(io_error),
85+
filepath,
86+
}
7687
}
7788
}
7889
/// Type of index incompatibility between the library and the index found on disk
7990
/// Used to catch and provide a hint to solve this incompatibility issue
91+
#[derive(Clone)]
8092
pub enum Incompatibility {
8193
/// This library cannot decompress the index found on disk
8294
CompressionMismatch {
@@ -135,7 +147,7 @@ impl fmt::Debug for Incompatibility {
135147
}
136148

137149
/// Error that may occur when accessing a file read
138-
#[derive(Debug, Error)]
150+
#[derive(Debug, Clone, Error)]
139151
pub enum OpenReadError {
140152
/// The file does not exists.
141153
#[error("Files does not exists: {0:?}")]
@@ -146,7 +158,7 @@ pub enum OpenReadError {
146158
)]
147159
IoError {
148160
/// The underlying `io::Error`.
149-
io_error: io::Error,
161+
io_error: Arc<io::Error>,
150162
/// File path of the file that tantivy failed to open for read.
151163
filepath: PathBuf,
152164
},
@@ -158,11 +170,14 @@ pub enum OpenReadError {
158170
impl OpenReadError {
159171
/// Wraps an io error.
160172
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
161-
Self::IoError { io_error, filepath }
173+
Self::IoError {
174+
io_error: Arc::new(io_error),
175+
filepath,
176+
}
162177
}
163178
}
164179
/// Error that may occur when trying to delete a file
165-
#[derive(Debug, Error)]
180+
#[derive(Debug, Clone, Error)]
166181
pub enum DeleteError {
167182
/// The file does not exists.
168183
#[error("File does not exists: '{0}'.")]
@@ -172,7 +187,7 @@ pub enum DeleteError {
172187
#[error("The following IO error happened while deleting file '{filepath}': '{io_error:?}'.")]
173188
IoError {
174189
/// The underlying `io::Error`.
175-
io_error: io::Error,
190+
io_error: Arc<io::Error>,
176191
/// File path of the file that tantivy failed to delete.
177192
filepath: PathBuf,
178193
},

src/directory/managed_directory.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,13 @@ impl ManagedDirectory {
242242
/// Verify checksum of a managed file
243243
pub fn validate_checksum(&self, path: &Path) -> result::Result<bool, OpenReadError> {
244244
let reader = self.directory.open_read(path)?;
245-
let (footer, data) =
246-
Footer::extract_footer(reader).map_err(|io_error| OpenReadError::IoError {
247-
io_error,
248-
filepath: path.to_path_buf(),
249-
})?;
245+
let (footer, data) = Footer::extract_footer(reader)
246+
.map_err(|io_error| OpenReadError::wrap_io_error(io_error, path.to_path_buf()))?;
250247
let bytes = data
251248
.read_bytes()
252249
.map_err(|io_error| OpenReadError::IoError {
250+
io_error: Arc::new(io_error),
253251
filepath: path.to_path_buf(),
254-
io_error,
255252
})?;
256253
let mut hasher = Hasher::new();
257254
hasher.update(bytes.as_slice());

src/directory/mmap_directory.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ impl MmapDirectory {
174174
/// This is mostly useful to test the MmapDirectory itself.
175175
/// For your unit tests, prefer the RamDirectory.
176176
pub fn create_from_tempdir() -> Result<MmapDirectory, OpenDirectoryError> {
177-
let tempdir = TempDir::new().map_err(OpenDirectoryError::FailedToCreateTempDir)?;
177+
let tempdir = TempDir::new()
178+
.map_err(|io_err| OpenDirectoryError::FailedToCreateTempDir(Arc::new(io_err)))?;
178179
Ok(MmapDirectory::new(
179180
tempdir.path().to_path_buf(),
180181
Some(tempdir),
@@ -342,7 +343,7 @@ impl Directory for MmapDirectory {
342343
DeleteError::FileDoesNotExist(path.to_owned())
343344
} else {
344345
DeleteError::IoError {
345-
io_error: e,
346+
io_error: Arc::new(e),
346347
filepath: path.to_path_buf(),
347348
}
348349
}
@@ -422,9 +423,9 @@ impl Directory for MmapDirectory {
422423
.write(true)
423424
.create(true) //< if the file does not exist yet, create it.
424425
.open(&full_path)
425-
.map_err(LockError::IoError)?;
426+
.map_err(LockError::wrap_io_error)?;
426427
if lock.is_blocking {
427-
file.lock_exclusive().map_err(LockError::IoError)?;
428+
file.lock_exclusive().map_err(LockError::wrap_io_error)?;
428429
} else {
429430
file.try_lock_exclusive().map_err(|_| LockError::LockBusy)?
430431
}

src/directory/ram_directory.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl Directory for RamDirectory {
172172
fn delete(&self, path: &Path) -> result::Result<(), DeleteError> {
173173
fail_point!("RamDirectory::delete", |_| {
174174
Err(DeleteError::IoError {
175-
io_error: io::Error::from(io::ErrorKind::Other),
175+
io_error: Arc::new(io::Error::from(io::ErrorKind::Other)),
176176
filepath: path.to_path_buf(),
177177
})
178178
});
@@ -184,7 +184,7 @@ impl Directory for RamDirectory {
184184
.fs
185185
.read()
186186
.map_err(|e| OpenReadError::IoError {
187-
io_error: io::Error::new(io::ErrorKind::Other, e.to_string()),
187+
io_error: Arc::new(io::Error::new(io::ErrorKind::Other, e.to_string())),
188188
filepath: path.to_path_buf(),
189189
})?
190190
.exists(path))
@@ -208,7 +208,7 @@ impl Directory for RamDirectory {
208208
self.open_read(path)?
209209
.read_bytes()
210210
.map_err(|io_error| OpenReadError::IoError {
211-
io_error,
211+
io_error: Arc::new(io_error),
212212
filepath: path.to_path_buf(),
213213
})?;
214214
Ok(bytes.as_slice().to_owned())

src/error.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Definition of Tantivy's errors and results.
22
33
use std::path::PathBuf;
4-
use std::sync::PoisonError;
4+
use std::sync::{Arc, PoisonError};
55
use std::{fmt, io};
66

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

5253
/// The library's error enum
53-
#[derive(Debug, Error)]
54+
#[derive(Debug, Clone, Error)]
5455
pub enum TantivyError {
5556
/// Failed to open the directory.
5657
#[error("Failed to open the directory: '{0:?}'")]
@@ -69,7 +70,7 @@ pub enum TantivyError {
6970
LockFailure(LockError, Option<String>),
7071
/// IO Error.
7172
#[error("An IO error occurred: '{0}'")]
72-
IoError(#[from] io::Error),
73+
IoError(Arc<io::Error>),
7374
/// Data corruption.
7475
#[error("Data corrupted: '{0:?}'")]
7576
DataCorruption(DataCorruption),
@@ -125,6 +126,11 @@ impl From<AsyncIoError> for TantivyError {
125126
}
126127
}
127128

129+
impl From<io::Error> for TantivyError {
130+
fn from(io_err: io::Error) -> TantivyError {
131+
TantivyError::IoError(Arc::new(io_err))
132+
}
133+
}
128134
impl From<DataCorruption> for TantivyError {
129135
fn from(data_corruption: DataCorruption) -> TantivyError {
130136
TantivyError::DataCorruption(data_corruption)
@@ -179,7 +185,7 @@ impl From<schema::DocParsingError> for TantivyError {
179185

180186
impl From<serde_json::Error> for TantivyError {
181187
fn from(error: serde_json::Error) -> TantivyError {
182-
TantivyError::IoError(error.into())
188+
TantivyError::IoError(Arc::new(error.into()))
183189
}
184190
}
185191

0 commit comments

Comments
 (0)