diff --git a/crates/milli/src/vector/error.rs b/crates/milli/src/vector/error.rs index 685022de8..00d4221e5 100644 --- a/crates/milli/src/vector/error.rs +++ b/crates/milli/src/vector/error.rs @@ -101,6 +101,32 @@ pub enum EmbedErrorKind { MissingEmbedding, #[error(transparent)] PanicInThreadPool(#[from] PanicCatched), + #[error("`media` requested but the configuration doesn't have source `rest`")] + RestMediaNotARest, + #[error("`media` requested, and the configuration has source `rest`, but the configuration doesn't have `searchFragments`.")] + RestMediaNotAFragment, + + #[error("Query matches multiple search fragments.\n - Note: First matched fragment `{name}`.\n - Note: Second matched fragment `{second_name}`.\n - Note: {}", + { + serde_json::json!({ + "q": q, + "media": media + }) + })] + RestSearchMatchesMultipleFragments { + name: String, + second_name: String, + q: Option, + media: Option, + }, + #[error("Query matches no search fragment.\n - Note: {}", + { + serde_json::json!({ + "q": q, + "media": media + }) + })] + RestSearchMatchesNoFragment { q: Option, media: Option }, } fn option_info(info: Option<&str>, prefix: &str) -> String { @@ -210,6 +236,44 @@ impl EmbedError { pub(crate) fn rest_extraction_error(error: String) -> EmbedError { Self { kind: EmbedErrorKind::RestExtractionError(error), fault: FaultSource::Runtime } } + + pub(crate) fn rest_media_not_a_rest() -> EmbedError { + Self { kind: EmbedErrorKind::RestMediaNotARest, fault: FaultSource::User } + } + + pub(crate) fn rest_media_not_a_fragment() -> EmbedError { + Self { kind: EmbedErrorKind::RestMediaNotAFragment, fault: FaultSource::User } + } + + pub(crate) fn rest_search_matches_multiple_fragments( + name: &str, + second_name: &str, + q: Option<&str>, + media: Option<&serde_json::Value>, + ) -> EmbedError { + Self { + kind: EmbedErrorKind::RestSearchMatchesMultipleFragments { + name: name.to_string(), + second_name: second_name.to_string(), + q: q.map(String::from), + media: media.cloned(), + }, + fault: FaultSource::User, + } + } + + pub(crate) fn rest_search_matches_no_fragment( + q: Option<&str>, + media: Option<&serde_json::Value>, + ) -> EmbedError { + Self { + kind: EmbedErrorKind::RestSearchMatchesNoFragment { + q: q.map(String::from), + media: media.cloned(), + }, + fault: FaultSource::User, + } + } } #[derive(Debug, thiserror::Error)] @@ -382,6 +446,13 @@ impl NewEmbedderError { fault: FaultSource::User, } } + + pub(crate) fn rest_cannot_infer_dimensions_for_fragment() -> NewEmbedderError { + Self { + kind: NewEmbedderErrorKind::RestCannotInferDimensionsForFragment, + fault: FaultSource::User, + } + } } #[derive(Debug, Clone, Copy)] @@ -499,6 +570,8 @@ pub enum NewEmbedderErrorKind { CompositeEmbeddingCountMismatch { search_count: usize, index_count: usize }, #[error("error while generating test embeddings.\n - the embeddings produced at search time and indexing time are not similar enough.\n - angular distance {distance:.2}\n - Meilisearch requires a maximum distance of {MAX_COMPOSITE_DISTANCE}.\n - Note: check that both embedders produce similar embeddings.{hint}")] CompositeEmbeddingValueMismatch { distance: f32, hint: CompositeEmbedderContainsHuggingFace }, + #[error("cannot infer `dimensions` for an embedder using `indexingFragments`.\n - Note: Specify `dimensions` explicitly or don't use `indexingFragments`.")] + RestCannotInferDimensionsForFragment, } pub struct PossibleEmbeddingMistakes {