elastic / elasticsearch-rs

Official Elasticsearch Rust Client
https://www.elastic.co/guide/en/elasticsearch/client/rust-api/current/index.html
Apache License 2.0
695 stars 70 forks source link

[BUG] When accessing response via json, null value thwarts deserialization #183

Closed PeterGrace closed 2 years ago

PeterGrace commented 2 years ago

Describe the bug A call to response.json().await fails with error: error decoding response body: invalid type: null, expected any valid TOML value at line 1 column 161. Upon further inspection, the null value is the response for max_score, I assume because I'm not actually executing a search that returns values, just an aggregation of data from the search.

data returned in the query (gathered by using response.text().await instead):

{"took":410,"timed_out":false,"_shards":{"total":450,"successful":450,"skipped":435,"failed":0},"hits":{"total":{"value":10000,"relation":"gte"},"max_score":null,"hits":[]},"aggregations":{"ingestLag":{"buckets":[{"key":60.0,"doc_count":530540} <snip>

To Reproduce Steps to reproduce the behavior:

    let mut response = client.search(SearchParts::Index(&["fastly-logs*"]))
        .body(json!({
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "ingest_time": {
              "gte": "now-10m",
              "lte": "now",
              "format": "epoch_millis"
            }
          }
        },
        {
          "query_string": {
            "analyze_wildcard": true,
            "query": "*"
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "ingestLag": {
      "histogram": {
        "field": "elk_ingest_lag",
        "interval": 30
      }
    }
  }
  }))
        .send()
        .await?;

    response = response.error_for_status_code()?;

    //let response_body = response.text().await.unwrap();
    //info!("{}", response_body);

       let response_body = match response.json::<Value>().await {
         Ok(s) => s,
         Err(e) => bail!("CANT DECODE: {}",e)
       };

Expected behavior The response.json().await call would produce a Value object containing the results of the query.

Environment (please complete the following information):

russcam commented 2 years ago

Thanks for opening @PeterGrace.

I've created a test for this in https://github.com/elastic/elasticsearch-rs/tree/bug/183, which passes OK. Based on the error message

error decoding response body: invalid type: null, expected any valid TOML value at line 1 column 161

Is it possible that theValue type in the response is a toml::value::Value and not a serde_json::value::Value?

PeterGrace commented 2 years ago

Is it possible that theValue type in the response is a toml::value::Value and not a serde_json::value::Value?

Well that's embarrassing! I must have hit the wrong option when I was importing in CLion and accidentally imported the toml Value instead. I was wondering why TOML would even be involved. Sorry for the noise, I'll close this one out.