1

Elasticsearch version 7.7.0

This is the part of the mapping:

const PROFILE_MAPPING = {
  mappings: {
    properties: {
      _userLocation: {
        type: "geo_point"
      },
      _ignoredBy: {
        type: "nested"
      }
    }
  }
};

_ignoredBy data example:

 [{
        "until" : "2020-12-03T16:20:43.176Z",
        "user" : <USER_ID>
  }]

and this is the script I'm running to update it:


    await client.update({
        index,
        id: target,
        refresh: "wait_for",
        body: {
          script: {
            source:
              "ctx._source._ignoredBy.removeIf(item -> item.user == 
    params.by.user);ctx._source._ignoredBy.add(params.by)",
            params: {
              by: {
                user: initiator,
                until: addSeconds(new Date(), ignoreInterval) 
              }
            }
          }
        }
      });

and this is the error I'm getting:

    {
      "error": {
        "root_cause": [
          {
            "type": "illegal_argument_exception",
            "reason": "failed to execute script"
          }
        ],
        "type": "illegal_argument_exception",
        "reason": "failed to execute script",
        "caused_by": {
          "type": "script_exception",
          "reason": "runtime error",
          "script_stack": ["item -> item.user == params.by.user);", "^---- HERE"],
          "script": "ctx._source._ignoredBy.removeIf(item -> item.user == params.by.user);ctx._source._ignoredBy.add(params.by)",
          "lang": "painless",
          "position": { "offset": 32, "start": 32, "end": 69 },
          "caused_by": { "type": "null_pointer_exception", "reason": null }
        }
      },
      "status": 400
    }

The weird thing is that this works 99% of the time but errors are appearing on logs and can't figure out what's the reason. The params passed in are 100% there as they appear on logs.

1 Answer 1

1

Such null pointers are hard to wrap one's head around but my hunch is that there's something off with ctx._source._ignoredBy itself.

In that spirit, I'd suggest to add one more check before I'm calling .removeIf on it -- perhaps initialize it in case it's null:

{
  "script": {
    "source": "if (ctx._source._ignoredBy == null) {ctx._source._ignoredBy = []; }  ctx._source._ignoredBy.removeIf(item -> item.user == params.by.user); ctx._source._ignoredBy.add(params.by)",
    "params": {
      ...
    }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Joe, if by any chance the _ignoredBy is empty, does it raises null pointer too, ie item does not exist? I do not know Java at all.
There's too little information for me to say that with confidence but I think so, yes. Painless is java-like so the same principles apply. Give my script a shot, wait a bit, and see if you're still seeing the 1% errors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.