2.0でエラーレスポンスのフォーマットが変わった

ElasticsearchのREST APIを叩いて戻ってくるレスポンスのフォーマットの話です。Elasticsearch 1.xでは検索が失敗した場合、search APIのレスポンスでerrorというフィールドに長い文字列でメッセージが書かれていました。

```js:1.7.3
{
  "error": "SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[YqBPkbNpSDqesBBnW_nqGw][test][0]: SearchParseException[[test][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": { \"term\": { \"c1\": \"ABC\" } }}]]]; nested: NumberFormatException[For input string: \"ABC\"]; }{[YqBPkbNpSDqesBBnW_nqGw][test][1]: SearchParseException[[test][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\":{ \"term\": { \"c1\": \"ABC\" } }}]]]; nested: NumberFormatException[For input string: \"ABC\"]; }{[YqBPkbNpSDqesBBnW_nqGw][test][2]: SearchParseException[[test][2]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": { \"term\": { \"c1\": \"ABC\" } }}]]]; nested: NumberFormatException[For input string: \"ABC\"]; }{[YqBPkbNpSDqesBBnW_nqGw][test][3]: SearchParseException[[test][3]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": { \"term\": { \"c1\": \"ABC\" } }}]]]; nested: NumberFormatException[For input string: \"ABC\"]; }{[YqBPkbNpSDqesBBnW_nqGw][test][4]: SearchParseException[[test][4]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": { \"term\":{ \"c1\": \"ABC\" } }}]]]; nested: NumberFormatException[For input string: \"ABC\"]; }]",
  "status": 400
}


```

これが2.0以降は下記のようにちゃんとしたJSON Objectが戻ってくるようになりました。

```js:2.1.0
{
  "error": {
    "root_cause": [
      {
        "type": "number_format_exception",
        "reason": "For input string: \"ABC\""
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shardsfailed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "test",
        "node": "T2VWCxc4SPefUE5Or-KNJg",
        "reason": {
          "type": "number_format_exception",
          "reason": "For input string: \"ABC\""
        }
      }
    ]
  },
  "status": 400
}
```

Bulk APIのレスポンスも1.xではエラーメッセージの中身からエラーの種類を把握しないとなりませんでした。

```js:1.7.1

{
  "took": 7,
  "errors": true,
  "items": [
    {
      "index": {
        "_index": "test",
        "_type": "int",
        "_id": "1",
        "status": 400,
        "error": "MapperParsingException[failed to parse [c1]]; nested: NumberFormatException[For input string: \"XYZ\"]; "
      }
    },
    {
      "index": {
        "_index": "test",
        "_type": "int",
        "_id": "2",
        "_version": 2,
        "status": 200
      }
    }
  ]
}

```

2.0では、searchに比べるとやや情報が少ないですが、error.typeフィールドでエラーコード的な文字列を取得できるようになりました。また、シャードごとにどのシャードが失敗したのかというのが_shardsメタフィールドから取得できます。

```js:2.1.0

{
  "took": 100,
  "errors": true,
  "items": [
    {
      "index": {
        "_index": "test",
        "_type": "int",
        "_id": "1",
        "status": 400,
        "error": {
          "type": "merge_mapping_exception",   // エラーコード
          "reason": "Merge failed with failures {[mapper [c1] of different type, current_type [string], merged_type [long]]}"
        }
      }
    },
    {
      "index": {
        "_index": "test",
        "_type": "int",
        "_id": "2",
        "_version": 1,
        "_shards": {            // シャード別の情報
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "status": 201
      }
    }
  ]
}

```