DynamoDB: transact_write_items() should return failing item (#5482)

This commit is contained in:
Bert Blommers 2022-09-17 09:50:31 +00:00 committed by GitHub
parent 5739db4701
commit e230750a7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 8 deletions

View File

@ -207,14 +207,14 @@ class TransactionCanceledException(DynamodbException):
def __init__(self, errors):
msg = self.cancel_reason_msg.format(
", ".join([str(code) for code, _ in errors])
", ".join([str(code) for code, _, _ in errors])
)
super().__init__(
error_type=TransactionCanceledException.error_type, message=msg
)
reasons = [
{"Code": code, "Message": message} if code else {"Code": "None"}
for code, message in errors
{"Code": code, "Message": message, **item} if code else {"Code": "None"}
for code, message, item in errors
]
self.description = json.dumps(
{

View File

@ -1654,7 +1654,7 @@ class DynamoDBBackend(BaseBackend):
raise MultipleTransactionsException()
target_items.add(item)
errors = []
errors = [] # [(Code, Message, Item), ..]
for item in transact_items:
try:
if "ConditionCheck" in item:
@ -1738,14 +1738,14 @@ class DynamoDBBackend(BaseBackend):
)
else:
raise ValueError
errors.append((None, None))
errors.append((None, None, None))
except MultipleTransactionsException:
# Rollback to the original state, and reraise the error
self.tables = original_table_state
raise MultipleTransactionsException()
except Exception as e: # noqa: E722 Do not use bare except
errors.append((type(e).__name__, e.message))
if set(errors) != set([(None, None)]):
errors.append((type(e).__name__, e.message, item))
if any([code is not None for code, _, _ in errors]):
# Rollback to the original state, and reraise the errors
self.tables = original_table_state
raise TransactionCanceledException(errors)

View File

@ -3882,7 +3882,11 @@ def test_transact_write_items_put_conditional_expressions():
reasons = ex.value.response["CancellationReasons"]
reasons.should.have.length_of(5)
reasons.should.contain(
{"Code": "ConditionalCheckFailed", "Message": "The conditional request failed"}
{
"Code": "ConditionalCheckFailed",
"Message": "The conditional request failed",
"Item": {"id": {"S": "foo2"}, "foo": {"S": "bar"}},
}
)
reasons.should.contain({"Code": "None"})
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)