No response type available for bulk operation result?
robinp opened this issue · 4 comments
robinp commented
Hello,
While there's an EsError
type, it doesn't seem suited to parse the error returned by a bulk op, for example:
{"took":0, "errors":true, "items":[
{"index":{"_index":"...","_type":"_doc","_id":"...","status":429,"error":{"type":"cluster_block_exception","reason":"index [xxx] blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block];"}}}]
(Note that this is a trimmed-down bulk request of 1 items, to simplify).
Pinging #144 on somewhat related.
robinp commented
FYI sketch of something:
data BulkResponse = BulkResponse
{ bulkTook :: Int
, bulkErrors :: Bool
, bulkActionItems :: [BulkActionItem]
}
deriving (Show, Generic)
data BulkActionItem = BulkActionItem
{ baiAction :: BulkAction
, baiItem :: BulkItem
}
deriving (Show, Generic)
data BulkItem = BulkItem
{ biIndex :: Text
, biId :: Text
, biStatus :: Maybe Int
, biError :: Maybe BulkError
}
deriving (Show, Generic)
data BulkAction = Index | Create | Delete | Update
deriving (Show, Generic)
data BulkError = BulkError
{ beType :: Text
, beReason :: Text
}
deriving (Show, Generic)
instance FromJSON BulkResponse where
parseJSON = withObject "BulkResponse" $ \o ->
BulkResponse <$> o .: "took" <*> o .: "errors" <*> o .: "items"
instance FromJSON BulkActionItem where
parseJSON j =
parseItem Index j
<|> parseItem Create j
<|> parseItem Delete j
<|> parseItem Update j
where
-- | The object has a single key: value pair, where the key encodes
-- the action.
parseItem :: BulkAction -> A.Value -> A.Parser BulkActionItem
parseItem action = withObject "BulkActionItem" $ \o -> do
v <- o .: toS actionText
pure $! BulkActionItem { baiAction = action, baiItem = v }
where
actionText :: Text
actionText = case action of
Index -> "index"
Create -> "create"
Delete -> "delete"
Update -> "update"
instance FromJSON BulkItem where
parseJSON = withObject "BulkItem" $ \o ->
BulkItem
<$> o
.: "_index"
<*> o
.: "_id"
<*> o
.:? "status" -- allegedly present but ES example shows a case where it is missing.. so..
<*> o
.:? "error"
instance FromJSON BulkError where
parseJSON = withObject "BulkError"
$ \o -> BulkError <$> o .: "type" <*> o .: "reason"
testErrorBody :: Text
testErrorBody = [text|
{"took":0,"errors":true,"items":[{"index":{"_index":"theidx","_type":"_doc","_id":"some:id:1","status":429,"error":{"type":"cluster_block_exception","reason":"index [theidx] blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block];"}}}]}
|]
testSuccessBody :: Text
testSuccessBody = [text|
{"took":7, "errors": false, "items":[{"index":{"_index":"test","_id":"1","_version":1,"result":"created","forced_refresh":false}}]}
|]
Feel free to use.
blackheaven commented
Thanks for your report and your contribution, I'll have a look tomorrow.
blackheaven commented
I have pushed it! Thanks a lot!
robinp commented
Thank you! Just a not for posterity, one still needs to use the parseEsResponse
helper, since on full-batch level errors, ES still returns that kind of error.