📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-8.9

1. 错误异常的基本描述 #

这个异常出现在解析邮件模板对象时。Watcher 期望在模板对象里读到明确的字段名,比如 texthtml;如果解析到一个值时,当前没有对应字段名,就会抛出 empty field

常见触发情形是对象结构损坏,例如模板渲染后生成了非法 JSON,导致解析器进入对象后拿到值,却没有前置字段名。

2. 为什么会发生这个错误 #

附带源码的关键判断如下:

if (token == XContentParser.Token.FIELD_NAME) {
    currentFieldName = parser.currentName();
} else if (currentFieldName == null) {
    throw new ElasticsearchParseException("could not parse email template. empty [{}] field", fieldName);
}

说明根因不在模板内容本身,而在模板对象的 JSON 结构。常见原因:

  • bodybody.html / body.text 对象被错误拼接。
  • 模板引擎输出了裸值,而不是 key: value 对。
  • 某段模板被截断,导致字段名丢失。
  • 手工编辑 watch 时写出了不完整对象。

3. 排查方法 #

  1. 查看邮件模板对应的完整 JSON,而不是只看模板字符串。
  2. 确认 bodybody.textbody.html 的层级是不是完整对象。
  3. 如果用了 Mustache 或外部模板变量,打印渲染后的最终结果。
  4. 优先定位是否存在对象开头后直接出现值、逗号位置错误或字段名缺失。

4. 如何解决这个错误 #

确保模板对象结构合法,例如:

{
  "email": {
    "body": {
      "text": "{{ctx.payload.message}}",
      "html": "<b>{{ctx.payload.message}}</b>"
    }
  }
}

如果只需要一种正文格式,只保留一个合法字段即可,不要生成空 key 或半截对象。

5. 预防建议 #

  • 对生成的 watch JSON 做语法校验。
  • 将邮件模板构造逻辑集中管理,减少手工拼接 JSON。
  • 在模板上线前保留一个最小可执行样例做解析测试。

相关错误 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

    String currentFieldName = null;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
        if (token == XContentParser.Token.FIELD_NAME) {
            currentFieldName = parser.currentName();
        } else if (currentFieldName == null) {
            throw new ElasticsearchParseException("could not parse email template. empty [{}] field", fieldName);
        } else if (Email.Field.BODY_TEXT.match(currentFieldName, parser.getDeprecationHandler())) {
            builder.textBody(TextTemplate.parse(parser));
        } else if (Email.Field.BODY_HTML.match(currentFieldName, parser.getDeprecationHandler())) {
            builder.htmlBody(TextTemplate.parse(parser));
        } else {