From b85180fedb410a90ce0af2fd88d44de35d81c249 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 24 Feb 2025 13:55:40 +0100 Subject: [PATCH] Error types --- crates/meilisearch-types/src/error.rs | 7 +-- crates/milli/src/error.rs | 64 ++++++++++++++++++++------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/crates/meilisearch-types/src/error.rs b/crates/meilisearch-types/src/error.rs index f64301b8c..5a0451b6c 100644 --- a/crates/meilisearch-types/src/error.rs +++ b/crates/meilisearch-types/src/error.rs @@ -428,9 +428,10 @@ impl ErrorCode for milli::Error { | UserError::InvalidUrl { .. } | UserError::InvalidSettingsDocumentTemplateMaxBytes { .. } | UserError::InvalidPrompt(_) - | UserError::InvalidDisableBinaryQuantization { .. } => { - Code::InvalidSettingsEmbedders - } + | UserError::InvalidDisableBinaryQuantization { .. } + | UserError::InvalidSourceForNested { .. } + | UserError::MissingSourceForNested { .. } + | UserError::InvalidSettingsEmbedder { .. } => Code::InvalidSettingsEmbedders, UserError::TooManyEmbedders(_) => Code::InvalidSettingsEmbedders, UserError::InvalidPromptForEmbeddings(..) => Code::InvalidSettingsEmbedders, UserError::NoPrimaryKeyCandidateFound => Code::IndexPrimaryKeyNoCandidateFound, diff --git a/crates/milli/src/error.rs b/crates/milli/src/error.rs index c8ed1912f..c977362d6 100644 --- a/crates/milli/src/error.rs +++ b/crates/milli/src/error.rs @@ -13,6 +13,7 @@ use thiserror::Error; use crate::constants::RESERVED_GEO_FIELD_NAME; use crate::documents::{self, DocumentsBatchCursorError}; use crate::thread_pool_no_abort::PanicCatched; +use crate::vector::settings::EmbeddingSettings; use crate::{CriterionError, DocumentId, FieldId, Object, SortError}; pub fn is_reserved_keyword(keyword: &str) -> bool { @@ -229,28 +230,52 @@ and can not be more than 511 bytes.", .document_id.to_string() InvalidSimilarEmbedder(String), #[error("Too many vectors for document with id {0}: found {1}, but limited to 256.")] TooManyVectors(String, usize), - #[error("`.embedders.{embedder_name}`: Field `{field}` unavailable for source `{source_}` (only available for sources: {}). Available fields: {}", - allowed_sources_for_field - .iter() - .map(|accepted| format!("`{}`", accepted)) - .collect::>() - .join(", "), - allowed_fields_for_source - .iter() - .map(|accepted| format!("`{}`", accepted)) - .collect::>() - .join(", ") + #[error("`.embedders.{embedder_name}`: Field `{field}` unavailable for source `{source_}`{for_context}.{available_sources}{available_fields}{available_contexts}", + field=field.name(), + for_context={ + context.in_context() + }, + available_sources={ + let allowed_sources_for_field = EmbeddingSettings::allowed_sources_for_field(*field, *context); + if allowed_sources_for_field.is_empty() { + String::new() + } else { + format!("\n - note: `{}` is available for sources: {}", + field.name(), + allowed_sources_for_field + .iter() + .map(|accepted| format!("`{}`", accepted)) + .collect::>() + .join(", "), + ) + } + }, + available_fields={ + let allowed_fields_for_source = EmbeddingSettings::allowed_fields_for_source(*source_, *context); + format!("\n - note: available fields for source `{source_}`{}: {}",context.in_context(), allowed_fields_for_source + .iter() + .map(|accepted| format!("`{}`", accepted)) + .collect::>() + .join(", "),) + }, + available_contexts={ + let available_not_nested = !matches!(EmbeddingSettings::field_status(*source_, *field, crate::vector::settings::NestingContext::NotNested), crate::vector::settings::FieldStatus::Disallowed); + if available_not_nested { + format!("\n - note: `{}` is available when source `{source_}` is not{}", field.name(), context.in_context()) + } else { + String::new() + } + } )] InvalidFieldForSource { embedder_name: String, source_: crate::vector::settings::EmbedderSource, - field: &'static str, - allowed_fields_for_source: &'static [&'static str], - allowed_sources_for_field: &'static [crate::vector::settings::EmbedderSource], + context: crate::vector::settings::NestingContext, + field: crate::vector::settings::MetaEmbeddingSetting, }, #[error("`.embedders.{embedder_name}.model`: Invalid model `{model}` for OpenAI. Supported models: {:?}", crate::vector::openai::EmbeddingModel::supported_models())] InvalidOpenAiModel { embedder_name: String, model: String }, - #[error("`.embedders.{embedder_name}`: Missing field `{field}` (note: this field is mandatory for source {source_})")] + #[error("`.embedders.{embedder_name}`: Missing field `{field}` (note: this field is mandatory for source `{source_}`)")] MissingFieldForSource { field: &'static str, source_: crate::vector::settings::EmbedderSource, @@ -270,6 +295,15 @@ and can not be more than 511 bytes.", .document_id.to_string() dimensions: usize, max_dimensions: usize, }, + #[error("`.embedders.{embedder_name}.source`: Source `{source_}` is not available in a nested embedder")] + InvalidSourceForNested { + embedder_name: String, + source_: crate::vector::settings::EmbedderSource, + }, + #[error("`.embedders.{embedder_name}`: Missing field `source`.\n - note: this field is mandatory for nested embedders")] + MissingSourceForNested { embedder_name: String }, + #[error("`.embedders.{embedder_name}`: {message}")] + InvalidSettingsEmbedder { embedder_name: String, message: String }, #[error("`.embedders.{embedder_name}.dimensions`: `dimensions` cannot be zero")] InvalidSettingsDimensions { embedder_name: String }, #[error(