Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No response type available for bulk operation result? #293

Closed
robinp opened this issue Feb 16, 2024 · 4 comments
Closed

No response type available for bulk operation result? #293

robinp opened this issue Feb 16, 2024 · 4 comments

Comments

@robinp
Copy link
Contributor

robinp commented Feb 16, 2024

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
Copy link
Contributor Author

robinp commented Feb 16, 2024

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
Copy link
Collaborator

Thanks for your report and your contribution, I'll have a look tomorrow.

@blackheaven
Copy link
Collaborator

I have pushed it! Thanks a lot!

@robinp
Copy link
Contributor Author

robinp commented Feb 19, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants