1use std::fmt::Debug;
2use std::io;
3use std::convert::From;
4
5use serde::{Serialize};
6use serde_json::error::Error as JsonError;
7
8use failure::Fail;
9
10use tantivy::directory::error::OpenDirectoryError;
11use tantivy::TantivyError;
12use tantivy::schema::DocParsingError;
13use tantivy::query::QueryParserError;
14
15
16#[derive(Debug, Fail, Clone, Serialize)]
17#[fail(display = "Message: {}", message)]
18pub struct IndexError {
19 message: String,
20 reason: String,
21
22}
23
24impl From<TantivyError> for IndexError {
25 fn from(error: TantivyError) -> Self {
26 Self::new("Unable to open Index", &error.to_string())
27 }
28}
29
30impl IndexError {
31 pub fn new<T: ToString>(message: T, reason: T) -> Self {
32 let message = message.to_string();
33 let reason = reason.to_string();
34 Self {
35 message,
36 reason,
37 }
38 }
39}
40
41impl From<OpenDirectoryError> for IndexError {
42 fn from(error: OpenDirectoryError) -> Self {
43 let message = "Unable to MMap directory for indexing".to_string();
44 let reason = error.to_string();
45 Self {
46 message,
47 reason,
48 }
49 }
50}
51
52
53impl From<io::Error> for IndexError {
54 fn from(error: io::Error) -> Self {
55 let message = "Unable to create index dir".to_string();
56 let reason = error.to_string();
57 Self {
58 message,
59 reason,
60 }
61 }
62}
63
64
65impl From<DocParsingError> for IndexError {
66 fn from(error: DocParsingError) -> Self {
67 let message = "Unable to parse document".to_string();
68 let reason = error.to_string();
69 Self {
70 message,
71 reason,
72 }
73 }
74}
75
76impl From<QueryParserError> for IndexError {
77 fn from(error: QueryParserError) -> Self {
78 let message = "Unable to parse query".to_string();
79 let reason = error.to_string();
80 Self {
81 message,
82 reason,
83 }
84 }
85}
86
87impl From<JsonError> for IndexError {
88 fn from(error: JsonError) -> Self {
89 let message = "Unable to covert to json".to_string();
90 let reason = error.to_string();
91 Self {
92 message,
93 reason,
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use std::path::PathBuf;
102 use std::str::FromStr;
103 use std::io::ErrorKind;
104 use serde::{Deserialize};
105
106 #[derive(Serialize, Deserialize)]
107 struct Dummy {
108 x: String,
109 y: String,
110 z: u64,
111 }
112
113
114 #[test]
115 fn validate_index_error() {
116 let message = "message".to_string();
117 let reason = "reason".to_string();
118 let error = IndexError {
119 message,
120 reason,
121 };
122 assert_eq!(format!("{}", error), error.to_string());
123 assert_eq!(&error.message, "message");
124 assert_eq!(&error.reason, "reason");
125 }
126
127 #[test]
128 fn validate_index_error_from_tantivy_error() {
129 let error = TantivyError::IndexAlreadyExists;
130 let error: IndexError = error.into();
131 assert_eq!(format!("{}", error), error.to_string());
132 }
133
134 #[test]
135 fn validate_index_error_from_open_directory_error() {
136 let path = PathBuf::from_str("doesnotexist").unwrap();
137 assert_eq!(path.exists(), false);
138 let error = OpenDirectoryError::DoesNotExist(path);
139 let error: IndexError = error.into();
140 assert_eq!(format!("{}", error), error.to_string());
141 }
142
143 #[test]
144 fn validate_index_error_from_io_error() {
145 let error = io::Error::from(ErrorKind::PermissionDenied);
146 let error: IndexError = error.into();
147 assert_eq!(format!("{}", error), error.to_string());
148 }
149
150 #[test]
151 fn validate_index_error_from_doc_parsing_error() {
152 let error = DocParsingError::NoSuchFieldInSchema("bs_field is not present".to_string());
153 let error: IndexError = error.into();
154 assert_eq!(format!("{}", error), error.to_string());
155 }
156
157 #[test]
158 fn validate_index_error_from_query_parser_error() {
159 let error = QueryParserError::FieldDoesNotExist("bs_field is not yet present".to_string());
160 let error: IndexError = error.into();
161 assert_eq!(format!("{}", error), error.to_string());
162 }
163
164 #[test]
165 fn validate_index_error_from_json_error() {
166 let json: serde_json::Result<Dummy> = serde_json::from_str("{\"ss\": \"ss\"}");
167 assert!(json.is_err());
168 let json = json.err().unwrap();
169
170 let error: IndexError = json.into();
171 assert_eq!(format!("{}", error), error.to_string());
172 }
173}