MeiliSearch/meilisearch-core/src/error.rs

225 lines
7.4 KiB
Rust
Raw Normal View History

2019-10-18 13:05:28 +02:00
use crate::serde::{DeserializerError, SerializerError};
2019-10-11 16:16:21 +02:00
use serde_json::Error as SerdeJsonError;
2020-04-06 20:05:02 +02:00
use pest::error::Error as PestError;
use crate::filters::Rule;
2019-10-18 13:05:28 +02:00
use std::{error, fmt, io};
2019-10-03 15:04:11 +02:00
2020-02-02 22:59:19 +01:00
pub use bincode::Error as BincodeError;
2020-04-06 20:05:02 +02:00
pub use fst::Error as FstError;
pub use heed::Error as HeedError;
pub use pest::error as pest_error;
2020-02-02 22:59:19 +01:00
use meilisearch_error::{ErrorCode, Code};
2019-10-03 17:33:15 +02:00
pub type MResult<T> = Result<T, Error>;
2019-10-03 15:04:11 +02:00
#[derive(Debug)]
pub enum Error {
Bincode(bincode::Error),
Deserializer(DeserializerError),
FacetError(FacetError),
FilterParseError(PestError<Rule>),
Fst(fst::Error),
Heed(heed::Error),
IndexAlreadyExists,
Io(io::Error),
2020-01-10 18:20:30 +01:00
MaxFieldsLimitExceeded,
MissingDocumentId,
MissingPrimaryKey,
2020-01-13 19:10:58 +01:00
Schema(meilisearch_schema::Error),
SchemaMissing,
2019-10-11 16:16:21 +02:00
SerdeJson(SerdeJsonError),
Serializer(SerializerError),
VersionMismatch(String),
WordIndexMissing,
}
impl ErrorCode for Error {
fn error_code(&self) -> Code {
2020-05-26 11:32:03 +02:00
use Error::*;
match self {
FacetError(_) => Code::Facet,
FilterParseError(_) => Code::Filter,
IndexAlreadyExists => Code::IndexAlreadyExists,
2020-07-06 09:56:10 +02:00
MissingPrimaryKey => Code::MissingPrimaryKey,
2020-05-26 11:32:03 +02:00
MissingDocumentId => Code::MissingDocumentId,
MaxFieldsLimitExceeded => Code::MaxFieldsLimitExceeded,
Schema(s) => s.error_code(),
WordIndexMissing
| SchemaMissing => Code::InvalidState,
Heed(_)
| Fst(_)
| SerdeJson(_)
| Bincode(_)
| Serializer(_)
| Deserializer(_)
| VersionMismatch(_)
2020-05-26 11:32:03 +02:00
| Io(_) => Code::Internal,
}
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::Io(error)
}
2019-10-03 15:04:11 +02:00
}
2020-04-06 19:31:24 +02:00
impl From<PestError<Rule>> for Error {
fn from(error: PestError<Rule>) -> Error {
Error::FilterParseError(error.renamed_rules(|r| {
let s = match r {
Rule::or => "OR",
Rule::and => "AND",
Rule::not => "NOT",
Rule::string => "string",
Rule::word => "word",
2020-04-06 20:05:02 +02:00
Rule::greater => "field > value",
Rule::less => "field < value",
Rule::eq => "field = value",
Rule::leq => "field <= value",
Rule::geq => "field >= value",
2020-04-06 19:31:24 +02:00
Rule::key => "key",
_ => "other",
};
s.to_string()
}))
}
2020-05-05 22:19:34 +02:00
}
impl From<FacetError> for Error {
fn from(error: FacetError) -> Error {
Error::FacetError(error)
}
}
2020-04-06 19:31:24 +02:00
2020-01-13 19:10:58 +01:00
impl From<meilisearch_schema::Error> for Error {
fn from(error: meilisearch_schema::Error) -> Error {
Error::Schema(error)
}
}
2020-02-02 22:59:19 +01:00
impl From<HeedError> for Error {
fn from(error: HeedError) -> Error {
Error::Heed(error)
2019-10-03 15:04:11 +02:00
}
}
2020-02-02 22:59:19 +01:00
impl From<FstError> for Error {
fn from(error: FstError) -> Error {
Error::Fst(error)
2019-10-03 15:04:11 +02:00
}
}
2019-10-11 16:16:21 +02:00
impl From<SerdeJsonError> for Error {
fn from(error: SerdeJsonError) -> Error {
Error::SerdeJson(error)
2019-10-03 15:04:11 +02:00
}
}
2020-02-02 22:59:19 +01:00
impl From<BincodeError> for Error {
fn from(error: BincodeError) -> Error {
Error::Bincode(error)
2019-10-03 15:04:11 +02:00
}
}
impl From<SerializerError> for Error {
fn from(error: SerializerError) -> Error {
match error {
SerializerError::DocumentIdNotFound => Error::MissingDocumentId,
e => Error::Serializer(e),
}
2019-10-03 15:04:11 +02:00
}
}
impl From<DeserializerError> for Error {
fn from(error: DeserializerError) -> Error {
Error::Deserializer(error)
}
}
2019-10-03 15:04:11 +02:00
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
match self {
Bincode(e) => write!(f, "bincode error; {}", e),
Deserializer(e) => write!(f, "deserializer error; {}", e),
FacetError(e) => write!(f, "error processing facet filter: {}", e),
FilterParseError(e) => write!(f, "error parsing filter; {}", e),
Fst(e) => write!(f, "fst error; {}", e),
Heed(e) => write!(f, "heed error; {}", e),
IndexAlreadyExists => write!(f, "index already exists"),
Io(e) => write!(f, "{}", e),
2020-02-11 15:16:02 +01:00
MaxFieldsLimitExceeded => write!(f, "maximum number of fields in a document exceeded"),
MissingDocumentId => write!(f, "document id is missing"),
MissingPrimaryKey => write!(f, "schema cannot be built without a primary key"),
2020-02-11 15:16:02 +01:00
Schema(e) => write!(f, "schema error; {}", e),
SchemaMissing => write!(f, "this index does not have a schema"),
2019-10-11 16:16:21 +02:00
SerdeJson(e) => write!(f, "serde json error; {}", e),
Serializer(e) => write!(f, "serializer error; {}", e),
2020-07-20 14:42:47 +02:00
VersionMismatch(version) => write!(f, "Cannot open database, expected MeiliSearch engine version: {}, current engine version: {}.{}.{}",
version,
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
env!("CARGO_PKG_VERSION_PATCH")),
WordIndexMissing => write!(f, "this index does not have a word index"),
2019-10-03 15:04:11 +02:00
}
}
}
2019-10-18 13:05:28 +02:00
impl error::Error for Error {}
2019-10-03 15:04:11 +02:00
struct FilterParseError(PestError<Rule>);
impl fmt::Display for FilterParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::pest_error::LineColLocation::*;
let (line, column) = match self.0.line_col {
Span((line, _), (column, _)) => (line, column),
Pos((line, column)) => (line, column),
};
write!(f, "parsing error on line {} at column {}: {}", line, column, self.0.variant.message())
}
}
2020-05-05 22:19:34 +02:00
#[derive(Debug)]
pub enum FacetError {
EmptyArray,
ParsingError(String),
UnexpectedToken { expected: &'static [&'static str], found: String },
InvalidFormat(String),
AttributeNotFound(String),
AttributeNotSet { expected: Vec<String>, found: String },
InvalidDocumentAttribute(String),
2020-06-10 12:03:19 +02:00
NoAttributesForFaceting,
2020-05-05 22:19:34 +02:00
}
impl FacetError {
pub fn unexpected_token(expected: &'static [&'static str], found: impl ToString) -> FacetError {
FacetError::UnexpectedToken{ expected, found: found.to_string() }
}
pub fn attribute_not_set(expected: Vec<String>, found: impl ToString) -> FacetError {
FacetError::AttributeNotSet{ expected, found: found.to_string() }
}
}
impl fmt::Display for FacetError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use FacetError::*;
match self {
EmptyArray => write!(f, "empty array in facet filter is unspecified behavior"),
ParsingError(msg) => write!(f, "parsing error: {}", msg),
UnexpectedToken { expected, found } => write!(f, "unexpected token {}, expected {}", found, expected.join("or")),
InvalidFormat(found) => write!(f, "invalid facet: {}, facets should be \"facetName:facetValue\"", found),
AttributeNotFound(attr) => write!(f, "unknown {:?} attribute", attr),
AttributeNotSet { found, expected } => write!(f, "`{}` is not set as a faceted attribute. available facet attributes: {}", found, expected.join(", ")),
2020-05-05 22:28:46 +02:00
InvalidDocumentAttribute(attr) => write!(f, "invalid document attribute {}, accepted types: String and [String]", attr),
2020-06-10 12:03:19 +02:00
NoAttributesForFaceting => write!(f, "impossible to perform faceted search, no attributes for faceting are set"),
2020-05-05 22:19:34 +02:00
}
}
}