mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 07:56:28 +00:00 
			
		
		
		
	Improve errors and introduce a new InvalidSearchDistinct error code
This commit is contained in:
		| @@ -270,13 +270,14 @@ InvalidSimilarShowRankingScore        , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSearchShowRankingScoreDetails  , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSimilarShowRankingScoreDetails , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSearchSort                     , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSearchDistinct                 , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsDisplayedAttributes    , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsDistinctAttribute      , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsProximityPrecision     , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsFaceting               , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsFilterableAttributes   , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsPagination             , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsSearchCutoffMs           , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsSearchCutoffMs         , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsEmbedders              , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsRankingRules           , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidSettingsSearchableAttributes   , InvalidRequest       , BAD_REQUEST ; | ||||
| @@ -381,6 +382,7 @@ impl ErrorCode for milli::Error { | ||||
|                         Code::IndexPrimaryKeyMultipleCandidatesFound | ||||
|                     } | ||||
|                     UserError::PrimaryKeyCannotBeChanged(_) => Code::IndexPrimaryKeyAlreadyExists, | ||||
|                     UserError::InvalidDistinctAttribute { .. } => Code::InvalidSearchDistinct, | ||||
|                     UserError::SortRankingRuleMissing => Code::InvalidSearchSort, | ||||
|                     UserError::InvalidFacetsDistribution { .. } => Code::InvalidSearchFacets, | ||||
|                     UserError::InvalidSortableAttribute { .. } => Code::InvalidSearchSort, | ||||
|   | ||||
| @@ -61,8 +61,7 @@ pub struct SearchQueryGet { | ||||
|     filter: Option<String>, | ||||
|     #[deserr(default, error = DeserrQueryParamError<InvalidSearchSort>)] | ||||
|     sort: Option<String>, | ||||
|     // TODO change the InvalidSearchSort to InvalidSearchDistinct error | ||||
|     #[deserr(default, error = DeserrQueryParamError<InvalidSearchSort>)] | ||||
|     #[deserr(default, error = DeserrQueryParamError<InvalidSearchDistinct>)] | ||||
|     distinct: Option<String>, | ||||
|     #[deserr(default, error = DeserrQueryParamError<InvalidSearchShowMatchesPosition>)] | ||||
|     show_matches_position: Param<bool>, | ||||
|   | ||||
| @@ -75,8 +75,7 @@ pub struct SearchQuery { | ||||
|     pub filter: Option<Value>, | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchSort>)] | ||||
|     pub sort: Option<Vec<String>>, | ||||
|     // TODO Change the error to InvalidSearchDistinct | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchSort>)] | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchDistinct>)] | ||||
|     pub distinct: Option<String>, | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchFacets>)] | ||||
|     pub facets: Option<Vec<String>>, | ||||
| @@ -393,8 +392,7 @@ pub struct SearchQueryWithIndex { | ||||
|     pub filter: Option<Value>, | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchSort>)] | ||||
|     pub sort: Option<Vec<String>>, | ||||
|     // TODO change error to InvalidSearchDistinct | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchSort>)] | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchDistinct>)] | ||||
|     pub distinct: Option<String>, | ||||
|     #[deserr(default, error = DeserrJsonError<InvalidSearchFacets>)] | ||||
|     pub facets: Option<Vec<String>>, | ||||
|   | ||||
| @@ -134,6 +134,17 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco | ||||
|         } | ||||
|     )] | ||||
|     InvalidSortableAttribute { field: String, valid_fields: BTreeSet<String>, hidden_fields: bool }, | ||||
|     #[error("Attribute `{}` is not filterable and thus, cannot be used as distinct attribute. {}", | ||||
|         .field, | ||||
|         match .valid_fields.is_empty() { | ||||
|             true => "This index does not have configured filterable attributes.".to_string(), | ||||
|             false => format!("Available filterable attributes are: `{}{}`.", | ||||
|                     valid_fields.iter().map(AsRef::as_ref).collect::<Vec<&str>>().join(", "), | ||||
|                     .hidden_fields.then_some(", <..hidden-attributes>").unwrap_or(""), | ||||
|                 ), | ||||
|         } | ||||
|     )] | ||||
|     InvalidDistinctAttribute { field: String, valid_fields: BTreeSet<String>, hidden_fields: bool }, | ||||
|     #[error("Attribute `{}` is not facet-searchable. {}", | ||||
|         .field, | ||||
|         match .valid_fields.is_empty() { | ||||
|   | ||||
| @@ -11,8 +11,8 @@ use self::new::{execute_vector_search, PartialSearchResult}; | ||||
| use crate::score_details::{ScoreDetails, ScoringStrategy}; | ||||
| use crate::vector::Embedder; | ||||
| use crate::{ | ||||
|     execute_search, filtered_universe, AscDesc, DefaultSearchLogger, DocumentId, Index, Result, | ||||
|     SearchContext, TimeBudget, | ||||
|     execute_search, filtered_universe, AscDesc, DefaultSearchLogger, DocumentId, Error, Index, | ||||
|     Result, SearchContext, TimeBudget, UserError, | ||||
| }; | ||||
|  | ||||
| // Building these factories is not free. | ||||
| @@ -177,9 +177,15 @@ impl<'a> Search<'a> { | ||||
|         } | ||||
|  | ||||
|         if let Some(distinct) = &self.distinct { | ||||
|             if !ctx.index.filterable_fields(ctx.txn)?.contains(distinct) { | ||||
|                 // TODO return a real error message | ||||
|                 panic!("Distinct search field is not a filterable attribute"); | ||||
|             let filterable_fields = ctx.index.filterable_fields(ctx.txn)?; | ||||
|             if !filterable_fields.contains(distinct) { | ||||
|                 let (valid_fields, hidden_fields) = | ||||
|                     ctx.index.remove_hidden_fields(ctx.txn, filterable_fields)?; | ||||
|                 return Err(Error::UserError(UserError::InvalidDistinctAttribute { | ||||
|                     field: distinct.clone(), | ||||
|                     valid_fields, | ||||
|                     hidden_fields, | ||||
|                 })); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user