关于Rust AWS SDK DynamoDB条件检查失败精准定位的技术问询
Rust AWS SDK DynamoDB多条件检查失败定位问题
问题
Rust AWS SDK是否能够提供DynamoDB条件检查失败的具体位置信息?配置了多个条件检查,但错误响应未明确指出具体哪个条件校验失败。
异常信息示例
TransactionCanceledException(TransactionCanceledException { message: Some("事务已取消,请参考取消原因获取具体详情 [None, ConditionalCheckFailed]"), cancellation_reasons: Some([CancellationReason { item: None, code: Some("None"), message: None }, CancellationReason { item: None, code: Some("ConditionalCheckFailed"), message: Some("条件请求失败") }]), meta: ErrorMetadata { code: Some("TransactionCanceledException"), message: Some("事务已取消,请参考取消原因获取具体详情 [None, ConditionalCheckFailed]"),
代码示例
let request = client .transact_write_items() .set_transact_items(Some(transact_items)); match request.send().await { Err(err) => { match err.into_service_error() { aws_sdk_dynamodb::operation::transact_write_items::TransactWriteItemsError::TransactionCanceledException(i) => { println!("reason: {:?}", &i.cancellation_reasons().unwrap()); }, _ => todo!(), };
错误输出示例
[CancellationReason { item: None, code: Some("None"), message: None }, CancellationReason { item: None, code: Some("ConditionalCheckFailed"), message: Some("条件请求失败") }]
解决方案
目前Rust AWS SDK返回的TransactionCanceledException中的cancellation_reasons数组,顺序和你在transact_items中定义的操作顺序完全对应。也就是说,数组中第N个元素对应事务请求里的第N个操作。
比如你示例中的错误输出里,第二个CancellationReason标记了ConditionalCheckFailed,说明事务请求里的第二个操作触发了条件检查失败。
需要注意的是,DynamoDB本身不会返回具体的条件表达式失败细节,CancellationReason里的item字段默认也是None,所以只能通过操作顺序对应来定位失败的操作。
优化建议:添加操作映射定位
可以在构建事务操作时,维护一个操作名称和对应操作的映射列表,当收到错误时,根据cancellation_reasons的索引关联到具体操作:
// 定义操作名称与对应的事务操作 let ops_with_names = vec![ ("更新用户余额", transact_item1), ("扣减商品库存", transact_item2), ]; // 提取事务操作列表 let transact_items: Vec<_> = ops_with_names.iter().map(|(_, item)| item.clone()).collect(); let request = client .transact_write_items() .set_transact_items(Some(transact_items)); match request.send().await { Err(err) => { match err.into_service_error() { aws_sdk_dynamodb::operation::transact_write_items::TransactWriteItemsError::TransactionCanceledException(i) => { if let Some(reasons) = i.cancellation_reasons() { reasons.iter().enumerate().for_each(|(idx, reason)| { if reason.code() == Some("ConditionalCheckFailed") { // 根据索引获取对应的操作名称 let op_name = ops_with_names.get(idx).map(|(name, _)| name).unwrap_or(&"未知操作"); println!("条件检查失败的操作:{}", op_name); } }); } }, _ => todo!(), }; }, Ok(_) => println!("事务执行成功"), }
通过这种代码层面的映射,就能快速定位到触发条件检查失败的具体操作。
内容的提问来源于stack exchange,提问作者foreverything005
相关产品推荐
相关产品推荐

