Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent handling of invalid rendered JSON in search template APIs #101477

Closed
Mikep86 opened this issue Oct 27, 2023 · 2 comments · Fixed by #101518
Closed

Inconsistent handling of invalid rendered JSON in search template APIs #101477

Mikep86 opened this issue Oct 27, 2023 · 2 comments · Fixed by #101518
Labels
>bug :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team

Comments

@Mikep86
Copy link
Contributor

Mikep86 commented Oct 27, 2023

Elasticsearch Version

8.10.4

Installed Plugins

No response

Java Version

bundled

OS Version

Cloud

Problem Description

The search template API and render search template API handle invalid rendered JSON differently.

The search template API (correctly) returns a 400 response, while the render search template API returns a500 response. This is due to the fact that the render search template API implementation returns early from the convert method, skipping the code that would throw XContentParseException.

Steps to Reproduce

  1. Create a search template that will render invalid JSON:
PUT _scripts/test-search-template
{
  "script": {
    "lang": "mustache",
    "source": """
    {
      "query": {
        "multi_match": {
          "query": "{{query_string}}",
          "fields": [{{#text_fields}}"{{name}}^{{boost}}"{{/text_fields}}]
        }
      },
      "from": "{{from}}",
      "size": "{{size}}"
    }
    """,
    "params": {
      "query_string": "My query string"
    }
  }
}
  1. Use the search template API to run a query:
GET my-index/_search/template
{
  "id": "test-search-template",
  "params": {
    "text_fields": [
      {"name": "title", "boost": 10},
      {"name": "description", "boost": 5}
    ],
    "from": 0,
    "size": 10
  }
}

Observe the 400 response:

{
  "error": {
    "root_cause": [
      {
        "type": "x_content_parse_exception",
        "reason": """[6:33] Unexpected character ('"' (code 34)): was expecting comma to separate Array entries
 at [Source: (String)"
    {
      "query": {
        "multi_match": {
          "query": "",
          "fields": ["title^10""description^5"]
        }
      },
      "from": "0",
      "size": "10"
    }
    "; line: 6, column: 33]"""
      }
    ],
    "type": "x_content_parse_exception",
    "reason": """[6:33] Unexpected character ('"' (code 34)): was expecting comma to separate Array entries
 at [Source: (String)"
    {
      "query": {
        "multi_match": {
          "query": "",
          "fields": ["title^10""description^5"]
        }
      },
      "from": "0",
      "size": "10"
    }
    "; line: 6, column: 33]""",
    "caused_by": {
      "type": "json_parse_exception",
      "reason": """Unexpected character ('"' (code 34)): was expecting comma to separate Array entries
 at [Source: (String)"
    {
      "query": {
        "multi_match": {
          "query": "",
          "fields": ["title^10""description^5"]
        }
      },
      "from": "0",
      "size": "10"
    }
    "; line: 6, column: 33]"""
    }
  },
  "status": 400
}
  1. Use the render search template API to render the search template:
POST _render/template
{
  "id": "test-search-template",
  "params": {
    "text_fields": [
      {"name": "title", "boost": 10},
      {"name": "description", "boost": 5}
    ],
    "from": 0,
    "size": 10
  }
}

Observe the 500 response:

{
  "error": {
    "root_cause": [
      {
        "type": "json_parse_exception",
        "reason": """Unexpected character ('"' (code 34)): was expecting comma to separate Array entries
 at [Source: (org.elasticsearch.common.io.stream.ByteBufferStreamInput); line: 6, column: 33]"""
      }
    ],
    "type": "json_parse_exception",
    "reason": """Unexpected character ('"' (code 34)): was expecting comma to separate Array entries
 at [Source: (org.elasticsearch.common.io.stream.ByteBufferStreamInput); line: 6, column: 33]""",
    "suppressed": [
      {
        "type": "illegal_state_exception",
        "reason": "Failed to close the XContentBuilder",
        "caused_by": {
          "type": "i_o_exception",
          "reason": "Unclosed object or array found"
        }
      }
    ]
  },
  "status": 500
}

Logs (if relevant)

No response

@Mikep86 Mikep86 added >bug needs:triage Requires assignment of a team area label :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team and removed needs:triage Requires assignment of a team area label labels Oct 27, 2023
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-search (Team:Search)

@kderusso kderusso added :EnterpriseSearch/Application Enterprise Search Team:Enterprise Search Meta label for Enterprise Search team and removed :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team labels Oct 27, 2023
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/ent-search-eng (Team:Enterprise Search)

@kderusso kderusso added :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team and removed :EnterpriseSearch/Application Enterprise Search Team:Enterprise Search Meta label for Enterprise Search team labels Oct 27, 2023
romseygeek added a commit that referenced this issue Oct 30, 2023
…01518)

If a mustache script that outputs badly-formed json is referred to in a render
template request, then the error returned will be a 500 server error, rather than
a 400 json parsing error. This is because rendering templates skips json parsing,
and so the error ends up being caught in the REST layer instead.

This commit changes the template rendering logic to always parse the output of
the script, catching json errors higher in the stack and allowing us to return
the correct status code. This also means that errors are correctly detected and
returned as part of multi search template requests.

Fixes #101477
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants