4846: Add OpenAI tests r=dureuill a=dureuill

# Pull Request

## Related issue
Part of fixing #4757 

## What does this PR do?
- OpenAI embedder: don't pass apiKey when it is empty (slightly improves error messages)
- rest embedder and rest-based embedders: specialize the authorization denied error message depending on the configuration source
- fix existing tests
- Adds assets containing prerecorded texts to embed and the embeddings obtained from OpenAI
- Adds an asset containing a tokenized long document and the embedding obtained from OpenAI for this token
- Uses the wiremock crate to mock the OpenAI API: parse the openai request, lookup the response in assets, craft an openai response


Co-authored-by: Louis Dureuil <louis@meilisearch.com>
This commit is contained in:
meili-bors[bot] 2024-08-05 10:49:28 +00:00 committed by GitHub
commit 57f7af77c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 1969 additions and 75 deletions

View File

@ -81,6 +81,7 @@ impl Display for Value {
f, f,
"{}", "{}",
json_string!(self, { json_string!(self, {
".uid" => "[uid]",
".enqueuedAt" => "[date]", ".enqueuedAt" => "[date]",
".startedAt" => "[date]", ".startedAt" => "[date]",
".finishedAt" => "[date]", ".finishedAt" => "[date]",

View File

@ -1110,7 +1110,7 @@ async fn document_addition_with_huge_int_primary_key() {
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1402,7 +1402,7 @@ async fn error_document_field_limit_reached_over_multiple_documents() {
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1436,7 +1436,7 @@ async fn error_document_field_limit_reached_over_multiple_documents() {
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1485,7 +1485,7 @@ async fn error_document_field_limit_reached_in_one_nested_document() {
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1528,7 +1528,7 @@ async fn error_document_field_limit_reached_over_multiple_documents_with_nested_
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1563,7 +1563,7 @@ async fn error_document_field_limit_reached_over_multiple_documents_with_nested_
snapshot!(response, snapshot!(response,
@r###" @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -2209,7 +2209,7 @@ async fn add_invalid_geo_and_then_settings() {
let ret = index.wait_task(ret.uid()).await; let ret = index.wait_task(ret.uid()).await;
snapshot!(ret, @r###" snapshot!(ret, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -2231,7 +2231,7 @@ async fn add_invalid_geo_and_then_settings() {
let ret = index.wait_task(ret.uid()).await; let ret = index.wait_task(ret.uid()).await;
snapshot!(ret, @r###" snapshot!(ret, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/dumps/mod.rs source: meilisearch/tests/dumps/mod.rs
--- ---
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "pets", "indexUid": "pets",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/dumps/mod.rs source: meilisearch/tests/dumps/mod.rs
--- ---
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "pets", "indexUid": "pets",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/search/distinct.rs source: meilisearch/tests/search/distinct.rs
--- ---
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "tamo", "indexUid": "tamo",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/search/errors.rs source: meilisearch/tests/search/errors.rs
--- ---
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "tamo", "indexUid": "tamo",
"status": "succeeded", "status": "succeeded",
"type": "indexCreation", "type": "indexCreation",

View File

@ -744,7 +744,7 @@ async fn test_summarized_index_deletion() {
snapshot!(task, snapshot!(task,
@r###" @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "failed", "status": "failed",
"type": "indexDeletion", "type": "indexDeletion",
@ -774,7 +774,7 @@ async fn test_summarized_index_deletion() {
snapshot!(task, snapshot!(task,
@r###" @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -796,7 +796,7 @@ async fn test_summarized_index_deletion() {
snapshot!(task, snapshot!(task,
@r###" @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "succeeded", "status": "succeeded",
"type": "indexDeletion", "type": "indexDeletion",
@ -818,7 +818,7 @@ async fn test_summarized_index_deletion() {
snapshot!(task, snapshot!(task,
@r###" @r###"
{ {
"uid": 3, "uid": "[uid]",
"indexUid": "test", "indexUid": "test",
"status": "failed", "status": "failed",
"type": "indexDeletion", "type": "indexDeletion",

Binary file not shown.

View File

@ -1,3 +1,4 @@
mod openai;
mod rest; mod rest;
mod settings; mod settings;
@ -7,6 +8,22 @@ use crate::common::index::Index;
use crate::common::{GetAllDocumentsOptions, Server}; use crate::common::{GetAllDocumentsOptions, Server};
use crate::json; use crate::json;
async fn get_server_vector() -> Server {
let server = Server::new().await;
let (value, code) = server.set_features(json!({"vectorStore": true})).await;
snapshot!(code, @"200 OK");
snapshot!(value, @r###"
{
"vectorStore": true,
"metrics": false,
"logsRoute": false,
"editDocumentsByFunction": false,
"containsFilter": false
}
"###);
server
}
#[actix_rt::test] #[actix_rt::test]
async fn add_remove_user_provided() { async fn add_remove_user_provided() {
let server = Server::new().await; let server = Server::new().await;
@ -218,7 +235,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -247,7 +264,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 3, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -277,7 +294,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 4, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -306,7 +323,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 5, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -335,7 +352,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 6, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -364,7 +381,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 7, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -405,7 +422,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 10, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -433,7 +450,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 11, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -461,7 +478,7 @@ async fn user_provided_embeddings_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 12, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -497,7 +514,7 @@ async fn user_provided_vectors_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -526,7 +543,7 @@ async fn user_provided_vectors_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 3, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -555,7 +572,7 @@ async fn user_provided_vectors_error() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 4, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -5,9 +5,9 @@ use reqwest::IntoUrl;
use wiremock::matchers::{method, path}; use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, Request, ResponseTemplate}; use wiremock::{Mock, MockServer, Request, ResponseTemplate};
use crate::common::{Server, Value}; use crate::common::Value;
use crate::json; use crate::json;
use crate::vector::GetAllDocumentsOptions; use crate::vector::{get_server_vector, GetAllDocumentsOptions};
async fn create_mock() -> (MockServer, Value) { async fn create_mock() -> (MockServer, Value) {
let mock_server = MockServer::start().await; let mock_server = MockServer::start().await;
@ -265,22 +265,6 @@ async fn dummy_testing_the_mock() {
snapshot!(body, @r###"{"data":[4,4,4]}"###); snapshot!(body, @r###"{"data":[4,4,4]}"###);
} }
async fn get_server_vector() -> Server {
let server = Server::new().await;
let (value, code) = server.set_features(json!({"vectorStore": true})).await;
snapshot!(code, @"200 OK");
snapshot!(value, @r###"
{
"vectorStore": true,
"metrics": false,
"logsRoute": false,
"editDocumentsByFunction": false,
"containsFilter": false
}
"###);
server
}
#[actix_rt::test] #[actix_rt::test]
async fn bad_request() { async fn bad_request() {
let (mock, _setting) = create_mock().await; let (mock, _setting) = create_mock().await;
@ -896,7 +880,7 @@ async fn bad_settings() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -941,7 +925,7 @@ async fn bad_settings() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -990,7 +974,7 @@ async fn add_vector_and_user_provided() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1086,7 +1070,7 @@ async fn server_returns_bad_request() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1125,7 +1109,7 @@ async fn server_returns_bad_request() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1154,7 +1138,7 @@ async fn server_returns_bad_request() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1198,7 +1182,7 @@ async fn server_returns_bad_response() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1251,7 +1235,7 @@ async fn server_returns_bad_response() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1306,7 +1290,7 @@ async fn server_returns_bad_response() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1361,7 +1345,7 @@ async fn server_returns_bad_response() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 3, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1426,7 +1410,7 @@ async fn server_returns_bad_response() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 4, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1493,7 +1477,7 @@ async fn server_returns_multiple() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1598,7 +1582,7 @@ async fn server_single_input_returns_in_array() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1703,7 +1687,7 @@ async fn server_raw() {
let task = index.wait_task(value.uid()).await; let task = index.wait_task(value.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",
@ -1800,7 +1784,7 @@ async fn server_custom_header() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1816,7 +1800,7 @@ async fn server_custom_header() {
} }
}, },
"error": { "error": {
"message": "Error while generating embeddings: runtime error: could not determine model dimensions:\n - test embedding failed with user error: could not authenticate against embedding server\n - server replied with `{\"error\":\"missing header 'my-nonstandard-auth'\"}`", "message": "Error while generating embeddings: runtime error: could not determine model dimensions:\n - test embedding failed with user error: could not authenticate against embedding server\n - server replied with `{\"error\":\"missing header 'my-nonstandard-auth'\"}`\n - Hint: Check the `apiKey` parameter in the embedder configuration",
"code": "vector_embedding_error", "code": "vector_embedding_error",
"type": "invalid_request", "type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#vector_embedding_error" "link": "https://docs.meilisearch.com/errors#vector_embedding_error"
@ -1839,7 +1823,7 @@ async fn server_custom_header() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "failed", "status": "failed",
"type": "settingsUpdate", "type": "settingsUpdate",
@ -1858,7 +1842,7 @@ async fn server_custom_header() {
} }
}, },
"error": { "error": {
"message": "Error while generating embeddings: runtime error: could not determine model dimensions:\n - test embedding failed with user error: could not authenticate against embedding server\n - server replied with `{\"error\":\"thou shall not pass, Balrog\"}`", "message": "Error while generating embeddings: runtime error: could not determine model dimensions:\n - test embedding failed with user error: could not authenticate against embedding server\n - server replied with `{\"error\":\"thou shall not pass, Balrog\"}`\n - Hint: Check the `apiKey` parameter in the embedder configuration",
"code": "vector_embedding_error", "code": "vector_embedding_error",
"type": "invalid_request", "type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#vector_embedding_error" "link": "https://docs.meilisearch.com/errors#vector_embedding_error"
@ -1881,7 +1865,7 @@ async fn server_custom_header() {
let task = server.wait_task(response.uid()).await; let task = server.wait_task(response.uid()).await;
snapshot!(task, @r###" snapshot!(task, @r###"
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -43,7 +43,7 @@ async fn update_embedder() {
let ret = server.wait_task(response.uid()).await; let ret = server.wait_task(response.uid()).await;
snapshot!(ret, @r###" snapshot!(ret, @r###"
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/vector/mod.rs source: meilisearch/tests/vector/mod.rs
--- ---
{ {
"uid": 1, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/vector/mod.rs source: meilisearch/tests/vector/mod.rs
--- ---
{ {
"uid": 2, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "documentAdditionOrUpdate", "type": "documentAdditionOrUpdate",

View File

@ -2,7 +2,7 @@
source: meilisearch/tests/vector/mod.rs source: meilisearch/tests/vector/mod.rs
--- ---
{ {
"uid": 0, "uid": "[uid]",
"indexUid": "doggo", "indexUid": "doggo",
"status": "succeeded", "status": "succeeded",
"type": "settingsUpdate", "type": "settingsUpdate",

View File

@ -62,8 +62,18 @@ pub enum EmbedErrorKind {
RestResponseDeserialization(std::io::Error), RestResponseDeserialization(std::io::Error),
#[error("expected a response containing {0} embeddings, got only {1}")] #[error("expected a response containing {0} embeddings, got only {1}")]
RestResponseEmbeddingCount(usize, usize), RestResponseEmbeddingCount(usize, usize),
#[error("could not authenticate against embedding server{}", option_info(.0.as_deref(), "server replied with "))] #[error("could not authenticate against {embedding} server{server_reply}{hint}", embedding=match *.1 {
RestUnauthorized(Option<String>), ConfigurationSource::User => "embedding",
ConfigurationSource::OpenAi => "OpenAI",
ConfigurationSource::Ollama => "ollama"
},
server_reply=option_info(.0.as_deref(), "server replied with "),
hint=match *.1 {
ConfigurationSource::User => "\n - Hint: Check the `apiKey` parameter in the embedder configuration",
ConfigurationSource::OpenAi => "\n - Hint: Check the `apiKey` parameter in the embedder configuration, and the `MEILI_OPENAI_API_KEY` and `OPENAI_API_KEY` environment variables",
ConfigurationSource::Ollama => "\n - Hint: Check the `apiKey` parameter in the embedder configuration"
})]
RestUnauthorized(Option<String>, ConfigurationSource),
#[error("sent too many requests to embedding server{}", option_info(.0.as_deref(), "server replied with "))] #[error("sent too many requests to embedding server{}", option_info(.0.as_deref(), "server replied with "))]
RestTooManyRequests(Option<String>), RestTooManyRequests(Option<String>),
#[error("sent a bad request to embedding server{}{}", #[error("sent a bad request to embedding server{}{}",
@ -136,8 +146,14 @@ impl EmbedError {
} }
} }
pub(crate) fn rest_unauthorized(error_response: Option<String>) -> EmbedError { pub(crate) fn rest_unauthorized(
Self { kind: EmbedErrorKind::RestUnauthorized(error_response), fault: FaultSource::User } error_response: Option<String>,
configuration_source: ConfigurationSource,
) -> EmbedError {
Self {
kind: EmbedErrorKind::RestUnauthorized(error_response, configuration_source),
fault: FaultSource::User,
}
} }
pub(crate) fn rest_too_many_requests(error_response: Option<String>) -> EmbedError { pub(crate) fn rest_too_many_requests(error_response: Option<String>) -> EmbedError {

View File

@ -183,7 +183,7 @@ impl Embedder {
let rest_embedder = RestEmbedder::new( let rest_embedder = RestEmbedder::new(
RestEmbedderOptions { RestEmbedderOptions {
api_key: Some(api_key.clone()), api_key: (!api_key.is_empty()).then(|| api_key.clone()),
distribution: None, distribution: None,
dimensions: Some(options.dimensions()), dimensions: Some(options.dimensions()),
url, url,

View File

@ -275,7 +275,10 @@ fn check_response(
Err(ureq::Error::Status(code, response)) => { Err(ureq::Error::Status(code, response)) => {
let error_response: Option<String> = response.into_string().ok(); let error_response: Option<String> = response.into_string().ok();
Err(match code { Err(match code {
401 => Retry::give_up(EmbedError::rest_unauthorized(error_response)), 401 => Retry::give_up(EmbedError::rest_unauthorized(
error_response,
configuration_source,
)),
429 => Retry::rate_limited(EmbedError::rest_too_many_requests(error_response)), 429 => Retry::rate_limited(EmbedError::rest_too_many_requests(error_response)),
400 => Retry::give_up(EmbedError::rest_bad_request( 400 => Retry::give_up(EmbedError::rest_bad_request(
error_response, error_response,