Skip to main content

lb_tantivy/
error.rs

1//! Definition of Tantivy's errors and results.
2
3use std::path::PathBuf;
4use std::sync::{Arc, PoisonError};
5use std::{fmt, io};
6
7use thiserror::Error;
8
9use crate::aggregation::AggregationError;
10use crate::directory::error::{
11    Incompatibility, LockError, OpenDirectoryError, OpenReadError, OpenWriteError,
12};
13use crate::fastfield::FastFieldNotAvailableError;
14use crate::schema::document::DeserializeError;
15use crate::{query, schema};
16
17/// Represents a `DataCorruption` error.
18///
19/// When facing data corruption, tantivy actually panics or returns this error.
20#[derive(Clone)]
21pub struct DataCorruption {
22    filepath: Option<PathBuf>,
23    comment: String,
24}
25
26impl DataCorruption {
27    /// Creates a `DataCorruption` Error.
28    pub fn new(filepath: PathBuf, comment: String) -> DataCorruption {
29        DataCorruption {
30            filepath: Some(filepath),
31            comment,
32        }
33    }
34
35    /// Creates a `DataCorruption` Error, when the filepath is irrelevant.
36    pub fn comment_only<TStr: ToString>(comment: TStr) -> DataCorruption {
37        DataCorruption {
38            filepath: None,
39            comment: comment.to_string(),
40        }
41    }
42}
43
44impl fmt::Debug for DataCorruption {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
46        write!(f, "Data corruption")?;
47        if let Some(ref filepath) = &self.filepath {
48            write!(f, " (in file `{filepath:?}`)")?;
49        }
50        write!(f, ": {}.", self.comment)?;
51        Ok(())
52    }
53}
54
55/// The library's error enum
56#[derive(Debug, Clone, Error)]
57pub enum TantivyError {
58    /// Error when handling aggregations.
59    #[error(transparent)]
60    AggregationError(#[from] AggregationError),
61    /// Failed to open the directory.
62    #[error("Failed to open the directory: '{0:?}'")]
63    OpenDirectoryError(#[from] OpenDirectoryError),
64    /// Failed to open a file for read.
65    #[error("Failed to open file for read: '{0:?}'")]
66    OpenReadError(#[from] OpenReadError),
67    /// Failed to open a file for write.
68    #[error("Failed to open file for write: '{0:?}'")]
69    OpenWriteError(#[from] OpenWriteError),
70    /// Index already exists in this directory.
71    #[error("Index already exists")]
72    IndexAlreadyExists,
73    /// Failed to acquire file lock.
74    #[error("Failed to acquire Lockfile: {0:?}. {1:?}")]
75    LockFailure(LockError, Option<String>),
76    /// IO Error.
77    #[error("An IO error occurred: '{0}'")]
78    IoError(Arc<io::Error>),
79    /// Data corruption.
80    #[error("Data corrupted: '{0:?}'")]
81    DataCorruption(DataCorruption),
82    /// A thread holding the locked panicked and poisoned the lock.
83    #[error("A thread holding the locked panicked and poisoned the lock")]
84    Poisoned,
85    /// The provided field name does not exist.
86    #[error("The field does not exist: '{0}'")]
87    FieldNotFound(String),
88    /// Invalid argument was passed by the user.
89    #[error("An invalid argument was passed: '{0}'")]
90    InvalidArgument(String),
91    /// An Error occurred in one of the threads.
92    #[error("An error occurred in a thread: '{0}'")]
93    ErrorInThread(String),
94    /// An Error occurred related to opening or creating a index.
95    #[error("Missing required index builder argument when open/create index: '{0}'")]
96    IndexBuilderMissingArgument(&'static str),
97    /// An Error occurred related to the schema.
98    #[error("Schema error: '{0}'")]
99    SchemaError(String),
100    /// System error. (e.g.: We failed spawning a new thread).
101    #[error("System error.'{0}'")]
102    SystemError(String),
103    /// Index incompatible with current version of Tantivy.
104    #[error("{0:?}")]
105    IncompatibleIndex(Incompatibility),
106    /// An internal error occurred. This is are internal states that should not be reached.
107    /// e.g. a datastructure is incorrectly inititalized.
108    #[error("Internal error: '{0}'")]
109    InternalError(String),
110    #[error("Deserialize error: {0}")]
111    /// An error occurred while attempting to deserialize a document.
112    DeserializeError(DeserializeError),
113}
114
115impl From<io::Error> for TantivyError {
116    fn from(io_err: io::Error) -> TantivyError {
117        TantivyError::IoError(Arc::new(io_err))
118    }
119}
120impl From<DataCorruption> for TantivyError {
121    fn from(data_corruption: DataCorruption) -> TantivyError {
122        TantivyError::DataCorruption(data_corruption)
123    }
124}
125impl From<FastFieldNotAvailableError> for TantivyError {
126    fn from(fastfield_error: FastFieldNotAvailableError) -> TantivyError {
127        TantivyError::SchemaError(format!("{fastfield_error}"))
128    }
129}
130impl From<LockError> for TantivyError {
131    fn from(lock_error: LockError) -> TantivyError {
132        TantivyError::LockFailure(lock_error, None)
133    }
134}
135
136impl From<query::QueryParserError> for TantivyError {
137    fn from(parsing_error: query::QueryParserError) -> TantivyError {
138        TantivyError::InvalidArgument(format!("Query is invalid. {parsing_error:?}"))
139    }
140}
141
142impl<Guard> From<PoisonError<Guard>> for TantivyError {
143    fn from(_: PoisonError<Guard>) -> TantivyError {
144        TantivyError::Poisoned
145    }
146}
147
148impl From<time::error::Format> for TantivyError {
149    fn from(err: time::error::Format) -> TantivyError {
150        TantivyError::InvalidArgument(format!("Date formatting error: {err}"))
151    }
152}
153
154impl From<time::error::Parse> for TantivyError {
155    fn from(err: time::error::Parse) -> TantivyError {
156        TantivyError::InvalidArgument(format!("Date parsing error: {err}"))
157    }
158}
159
160impl From<time::error::ComponentRange> for TantivyError {
161    fn from(err: time::error::ComponentRange) -> TantivyError {
162        TantivyError::InvalidArgument(format!("Date range error: {err}"))
163    }
164}
165
166impl From<schema::DocParsingError> for TantivyError {
167    fn from(error: schema::DocParsingError) -> TantivyError {
168        TantivyError::InvalidArgument(format!("Failed to parse document {error:?}"))
169    }
170}
171
172impl From<serde_json::Error> for TantivyError {
173    fn from(error: serde_json::Error) -> TantivyError {
174        TantivyError::IoError(Arc::new(error.into()))
175    }
176}
177
178impl From<rayon::ThreadPoolBuildError> for TantivyError {
179    fn from(error: rayon::ThreadPoolBuildError) -> TantivyError {
180        TantivyError::SystemError(error.to_string())
181    }
182}
183
184impl From<DeserializeError> for TantivyError {
185    fn from(error: DeserializeError) -> TantivyError {
186        TantivyError::DeserializeError(error)
187    }
188}