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