diff --git a/meilisearch-core/src/error.rs b/meilisearch-core/src/error.rs index 62840c2a8..bbb33526a 100644 --- a/meilisearch-core/src/error.rs +++ b/meilisearch-core/src/error.rs @@ -183,6 +183,7 @@ pub enum FacetError { AttributeNotFound(String), AttributeNotSet { expected: Vec, found: String }, InvalidDocumentAttribute(String), + NoAttributesForFaceting, } impl FacetError { @@ -207,6 +208,7 @@ impl fmt::Display for FacetError { 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(", ")), InvalidDocumentAttribute(attr) => write!(f, "invalid document attribute {}, accepted types: String and [String]", attr), + NoAttributesForFaceting => write!(f, "impossible to perform faceted search, no attributes for faceting are set"), } } } diff --git a/meilisearch-core/src/facets.rs b/meilisearch-core/src/facets.rs index cc1737eaf..2f632dd94 100644 --- a/meilisearch-core/src/facets.rs +++ b/meilisearch-core/src/facets.rs @@ -35,6 +35,9 @@ impl FacetFilter { schema: &Schema, attributes_for_faceting: &[FieldId], ) -> MResult { + if attributes_for_faceting.is_empty() { + return Err(FacetError::NoAttributesForFaceting.into()); + } let parsed = serde_json::from_str::(s).map_err(|e| FacetError::ParsingError(e.to_string()))?; let mut filter = Vec::new(); match parsed { diff --git a/meilisearch-http/src/routes/search.rs b/meilisearch-http/src/routes/search.rs index 1a2521386..0d698eafb 100644 --- a/meilisearch-http/src/routes/search.rs +++ b/meilisearch-http/src/routes/search.rs @@ -87,10 +87,8 @@ async fn search_with_url_query( } if let Some(ref facet_filters) = params.facet_filters { - let attrs = index.main.attributes_for_faceting(&reader)?; - if let Some(attrs) = attrs { - search_builder.add_facet_filters(FacetFilter::from_str(facet_filters, &schema, &attrs)?); - } + let attrs = index.main.attributes_for_faceting(&reader)?.unwrap_or_default(); + search_builder.add_facet_filters(FacetFilter::from_str(facet_filters, &schema, &attrs)?); } if let Some(facets) = ¶ms.facets_distribution { diff --git a/meilisearch-http/tests/search.rs b/meilisearch-http/tests/search.rs index 4597ee7f1..39bb163eb 100644 --- a/meilisearch-http/tests/search.rs +++ b/meilisearch-http/tests/search.rs @@ -1257,8 +1257,9 @@ async fn test_faceted_search_invalid() { //no faceted attributes set let query = "q=a&facetFilters=%5B%22color%3Ablue%22,%20%22tags%3Abug%22%20%5D"; - let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + let (response, status_code) = server.search(query).await; + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); let body = json!({ "attributesForFaceting": ["color", "tags"] @@ -1268,29 +1269,35 @@ async fn test_faceted_search_invalid() { // [] let query = "q=a&facetFilters=%5B%5D"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); // [[]] let query = "q=a&facetFilters=%5B%5B%5D"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); // ["color:green", []] let query = "q=a&facetFilters=%5B%22color%3Agreen%22,%20%5B%5D"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); // too much depth // [[[]]] let query = "q=a&facetFilters=%5B%5B%5B%5D%5D%5D"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); // [["color:green", ["color:blue"]]] let query = "q=a&facetFilters=%5B%5B%22color%3Agreen%22,%20%5B%22color%3Ablue%22%5D%5D%5D"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); // "color:green" let query = "q=a&facetFilters=%22color%3Agreen%22"; let (_response, status_code) = server.search(query).await; - assert_ne!(status_code, 202); + assert_eq!(status_code, 400); + assert_eq!(response["errorCode"], "invalid_facet"); } #[actix_rt::test]