meilisearch/meilisearch-rust

Seeing an error with Request succeeded but failed to parse response Some(ParseError(Error("missing field `updateId`", line: 1, column: 121)))

lionkeng opened this issue · 7 comments

Description
Created a simple rust program that basically runs the example from the documentation.

use futures::executor::block_on;
use meilisearch_sdk::{client::*, document::*};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct Movie {
    id: usize,
    title: String,
    genres: Vec<String>,
}

// That trait is required to make a struct usable by an index
impl Document for Movie {
    type UIDType = usize;

    fn get_uid(&self) -> &Self::UIDType {
        &self.id
    }
}

fn main() {
    tracing_subscriber::fmt::init();

    block_on(async move {
        // Create a client (without sending any request so that can't fail)
        let client = Client::new("http://0.0.0.0:7700", "");

        // An index is where the documents are stored.
        let movies = client.index("movies");
        tracing::debug!("movies {:?}", movies);
        // Add some movies in the index. If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents.
        let res = movies
            .add_documents(
                &[
                    Movie {
                        id: 1,
                        title: String::from("Carol"),
                        genres: vec!["Romance".to_string(), "Drama".to_string()],
                    },
                    Movie {
                        id: 2,
                        title: String::from("Wonder Woman"),
                        genres: vec!["Action".to_string(), "Adventure".to_string()],
                    },
                    Movie {
                        id: 3,
                        title: String::from("Life of Pi"),
                        genres: vec!["Adventure".to_string(), "Drama".to_string()],
                    },
                    Movie {
                        id: 4,
                        title: String::from("Mad Max"),
                        genres: vec!["Adventure".to_string(), "Science Fiction".to_string()],
                    },
                    Movie {
                        id: 5,
                        title: String::from("Moana"),
                        genres: vec!["Fantasy".to_string(), "Action".to_string()],
                    },
                    Movie {
                        id: 6,
                        title: String::from("Philadelphia"),
                        genres: vec!["Drama".to_string()],
                    },
                ],
                Some("id"),
            )
            .await;
        if res.is_err() {
            println!("{:?}", res.err());
        }
    })
}

Expected behavior
No error when adding document.

Current behavior
ERROR meilisearch_sdk::request: Request succeeded but failed to parse response
Ran into error Some(ParseError(Error("missing field updateId", line: 1, column: 121)))

Screenshots or Logs
If applicable, add screenshots or logs to help explain your problem.

Environment (please complete the following information):

  • OS: [e.g. Debian GNU/Linux]
  • Meilisearch version: [e.g. v.0.25.2] in a docker container
  • meilisearch-rust version: [e.g v0.13.0]
docker run -it --rm \
    -p 7700:7700 \
    -v $(pwd)/data.ms:/data.ms \
    getmeili/meilisearch:latest

The meilisearch-rust SDK is not compatible with the latest version of meilisearch right now.
All the code has been written, though, and a new release should be published in a few hours/days.

If you want to test the code right now you can access it on the bump-meilisearch-v0.25.0 branch

I am using the branch bump-meilisearch-v0.25.0

While using this branch I use a command like :
let movies: Index = client.create_index("movies", Some("movie_id")).await.unwrap();
and this throws an error

mismatched types
expected struct meilisearch_sdk::indexes::Index, found enum TaskrustcE0308

I think it's supposed to return an Index but ends up returning a task instead.

Huum no, in the latest update of Meilisearch, the creation and deletion of indexes are now asynchronous so you don’t get an Index anymore when calling create_index.
You can do something like that though:

let movies: Index = client
  .create_index("movies", Some("movie_id"))
  .await
  .unwrap()
  .wait_for_completion(&client, None, None)
  .await
  .unwrap()
  .try_make_index(&client)
  .unwrap(); 

This did not work as it was saying try_make_index required 1 argument but got 0, I used something like this instead whcih worked, Thanks :

client.create_index(name_string, Some("object_id")).await.unwrap().wait_for_completion(&client, None, None)
             .await;
let index = client.get_index(name_string).await.unwrap();
            

I'm getting a similar error when adding the settings:

ParseError(Error(\"invalid type: map, expected u64\", line: 0, column: 0))

The code looks like:

let settings = Settings::new()
                      .with_searchable_attributes(["name", "title"])
                      .with_filterable_attributes(["created_at"]);

let _ = my_index
                      .set_settings(&settings)
                      .await.map_err(log_error); // <- Parse error returned here

I'm suspecting that somewhere down the line there's an invalid type cast to u64, but couldn't find any :/.

This did not work as it was saying try_make_index required 1 argument but got 0

Sorry for the huge delay I totally missed your message!
try_make_index is supposed the client as an argument, you can see the documentation here with a little example.
And I updated my comment thanks 👍


@moy2010 I tried to reproduce your issue but I don't know how to do!
Could you checkout this branch, then run cargo run --example settings and tell me if it throws any error?

Here you can see the code it'll execute; https://github.com/irevoire/meilisearch-rust/blob/settings-example/examples/settings.rs

Hi, @irevoire . I run your example, but it didn't fail. Although, I've narrowed down where the error comes from in my case.

I mistakenly thought that it was coming from when setting the settings, but it's in fact coming when creating the index (client.create_index), specifically when parsing the response body:

fn parse_response<Output: DeserializeOwned>(
    status_code: u16,
    expected_status_code: u16,
    body: String,
) -> Result<Output, Error> {
    if status_code == expected_status_code {
        match from_str::<Output>(&body) {
            Ok(output) => {
                trace!("Request succeed");
                return Ok(output);
            }
            Err(e) => {
                error!("Request succeeded but failed to parse response");
                return Err(Error::ParseError(e));
            }
        };

I can see in the console "Request succeeded but failed to parse response" right before the parse error.

I will ignore the error and add the settings anyway. If I can further reduce the scope of the error, will let you know.