bitemyapp / bloodhound

Haskell Elasticsearch client and query DSL
bitemyapp.com
BSD 3-Clause "New" or "Revised" License
424 stars 118 forks source link

`parseEsResponse` cannot parse version conflict error response (OpenSearch 1.3) #295

Closed supersven closed 1 month ago

supersven commented 1 month ago

Bloodhound version: 76a27a44223e8c24ec2c6a13504ea671887f2672 OpenSearch version: 1.3.19

Error:

EsProtocolException {
   esProtoExMessage = "Original error was: Non-200 status code Error parse failure was: Error in $: key \"error\" not found"
   , esProtoExResponse = "{\"took\":9,\"timed_out\":false,\"total\":3,\"updated\":1,\"deleted\":0,\"batches\":1,\"version_conflicts\":2,\"noops\":0,\"retries\":{\"bulk\":0,\"search\":0},\"throttled_millis\":0,\"requests_per_second\":-1.0,\"throttled_until_millis\":0,\"failures\":[{\"index\":\"directory_test\",\"type\":\"_doc\",\"id\":\"9fda4188-2afd-490d-8796-e023df61a4e9\",\"cause\":{\"type\":\"version_conflict_engine_exception\",\"reason\":\"[9fda4188-2afd-490d-8796-e023df61a4e9]: version conflict, required seqNo [11], primary term [1]. current document has seqNo [16] and primary term [1]\",\"index\":\"directory_test\",\"shard\":\"0\",\"index_uuid\":\"Y3RpVY_DQEW9ULn8oGulrg\"},\"status\":409},{\"index\":\"directory_test\",\"type\":\"_doc\",\"id\":\"d70b631d-966a-4951-a94c-35ddc210f28a\",\"cause\":{\"type\":\"version_conflict_engine_exception\",\"reason\":\"[d70b631d-966a-4951-a94c-35ddc210f28a]: version conflict, required seqNo [13], primary term [1]. current document has seqNo [15] and primary term [1]\",\"index\":\"directory_test\",\"shard\":\"0\",\"index_uuid\":\"Y3RpVY_DQEW9ULn8oGulrg\"},\"status\":409}]}"
}
supersven commented 1 month ago

To me it looks like the FromJSON EsError instance does not fit to the response.

instance FromJSON EsError where
  parseJSON (Object v) =
    EsError
      <$> v
        .:? "status"
      <*> (v .: "error" <|> (v .: "error" >>= (.: "reason")))
  parseJSON _ = empty

The implementation expects an error or error.reason field, while in the response there's an array (failures) with reasons.

Would it make sense to adjust the FromJSON EsError instance with one more alternative to match the response's structure?

blackheaven commented 1 month ago

Actually, at this point, ElasticSearch and OpenSearch are starting to diverge so much, I'm considering have their error types distinct.

supersven commented 1 month ago

diverge

@blackheaven Thanks a lot for looking into this!

I agree that in future separate types may make sense; especially, because the OpenSearch response carries more information than EsError.

However, I've created a quick-fix in https://github.com/bitemyapp/bloodhound/pull/301 . It adjusts the FromJSON instance to map some information into an EsError.