From a951515562d40aa93838311fcfa4a2a055f22233 Mon Sep 17 00:00:00 2001 From: AsyncAws Bot Date: Fri, 15 Aug 2025 06:36:47 +0000 Subject: [PATCH] update generated code --- manifest.json | 2 +- src/Service/DynamoDb/CHANGELOG.md | 4 + src/Service/DynamoDb/composer.json | 2 +- src/Service/DynamoDb/src/DynamoDbClient.php | 21 +++++ ...ProvisionedThroughputExceededException.php | 59 +++++++++++-- .../RequestLimitExceededException.php | 54 +++++++++++- .../src/Exception/ThrottlingException.php | 61 +++++++++++++ .../src/ValueObject/ThrottlingReason.php | 86 +++++++++++++++++++ 8 files changed, 279 insertions(+), 10 deletions(-) create mode 100644 src/Service/DynamoDb/src/Exception/ThrottlingException.php create mode 100644 src/Service/DynamoDb/src/ValueObject/ThrottlingReason.php diff --git a/manifest.json b/manifest.json index fb09b0956..d3981f6aa 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "variables": { - "${LATEST}": "3.352.4" + "${LATEST}": "3.354.0" }, "endpoints": "https://raw.githubusercontent.com/aws/aws-sdk-php/${LATEST}/src/data/endpoints.json", "services": { diff --git a/src/Service/DynamoDb/CHANGELOG.md b/src/Service/DynamoDb/CHANGELOG.md index 5ebf39d33..4502e6b51 100644 --- a/src/Service/DynamoDb/CHANGELOG.md +++ b/src/Service/DynamoDb/CHANGELOG.md @@ -2,6 +2,10 @@ ## NOT RELEASED +### Added + +- AWS api-change: This release 1/ Adds support for throttled keys mode for CloudWatch Contributor Insights, 2/ Adds throttling reasons to exceptions across dataplane APIs. 3/ Explicitly models ThrottlingException as a class in statically typed languages. Refer to the launch day blog post for more details. + ## 3.7.0 ### Added diff --git a/src/Service/DynamoDb/composer.json b/src/Service/DynamoDb/composer.json index bbd595c75..43a2b4799 100644 --- a/src/Service/DynamoDb/composer.json +++ b/src/Service/DynamoDb/composer.json @@ -32,7 +32,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.7-dev" + "dev-master": "3.8-dev" } } } diff --git a/src/Service/DynamoDb/src/DynamoDbClient.php b/src/Service/DynamoDb/src/DynamoDbClient.php index d3d72e130..090cd5fbe 100644 --- a/src/Service/DynamoDb/src/DynamoDbClient.php +++ b/src/Service/DynamoDb/src/DynamoDbClient.php @@ -27,6 +27,7 @@ use AsyncAws\DynamoDb\Exception\RequestLimitExceededException; use AsyncAws\DynamoDb\Exception\ResourceInUseException; use AsyncAws\DynamoDb\Exception\ResourceNotFoundException; +use AsyncAws\DynamoDb\Exception\ThrottlingException; use AsyncAws\DynamoDb\Exception\TransactionCanceledException; use AsyncAws\DynamoDb\Exception\TransactionConflictException; use AsyncAws\DynamoDb\Exception\TransactionInProgressException; @@ -150,6 +151,7 @@ class DynamoDbClient extends AbstractApi * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException */ public function batchGetItem($input): BatchGetItemOutput { @@ -159,6 +161,7 @@ public function batchGetItem($input): BatchGetItemOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, ], 'usesEndpointDiscovery' => true])); return new BatchGetItemOutput($response, $this, $input); @@ -245,6 +248,7 @@ public function batchGetItem($input): BatchGetItemOutput * @throws ReplicatedWriteConflictException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException */ public function batchWriteItem($input): BatchWriteItemOutput { @@ -256,6 +260,7 @@ public function batchWriteItem($input): BatchWriteItemOutput 'ReplicatedWriteConflictException' => ReplicatedWriteConflictException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, ], 'usesEndpointDiscovery' => true])); return new BatchWriteItemOutput($response); @@ -352,6 +357,7 @@ public function createTable($input): CreateTableOutput * @throws ReplicatedWriteConflictException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException * @throws TransactionConflictException */ public function deleteItem($input): DeleteItemOutput @@ -365,6 +371,7 @@ public function deleteItem($input): DeleteItemOutput 'ReplicatedWriteConflictException' => ReplicatedWriteConflictException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, 'TransactionConflictException' => TransactionConflictException::class, ], 'usesEndpointDiscovery' => true])); @@ -502,6 +509,7 @@ public function describeTable($input): DescribeTableOutput * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException * @throws TransactionConflictException */ public function executeStatement($input): ExecuteStatementOutput @@ -515,6 +523,7 @@ public function executeStatement($input): ExecuteStatementOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, 'TransactionConflictException' => TransactionConflictException::class, ]])); @@ -547,6 +556,7 @@ public function executeStatement($input): ExecuteStatementOutput * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException */ public function getItem($input): GetItemOutput { @@ -556,6 +566,7 @@ public function getItem($input): GetItemOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, ], 'usesEndpointDiscovery' => true])); return new GetItemOutput($response); @@ -635,6 +646,7 @@ public function listTables($input = []): ListTablesOutput * @throws ReplicatedWriteConflictException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException * @throws TransactionConflictException */ public function putItem($input): PutItemOutput @@ -648,6 +660,7 @@ public function putItem($input): PutItemOutput 'ReplicatedWriteConflictException' => ReplicatedWriteConflictException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, 'TransactionConflictException' => TransactionConflictException::class, ], 'usesEndpointDiscovery' => true])); @@ -724,6 +737,7 @@ public function putItem($input): PutItemOutput * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException */ public function query($input): QueryOutput { @@ -733,6 +747,7 @@ public function query($input): QueryOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, ], 'usesEndpointDiscovery' => true])); return new QueryOutput($response, $this, $input); @@ -801,6 +816,7 @@ public function query($input): QueryOutput * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException */ public function scan($input): ScanOutput { @@ -810,6 +826,7 @@ public function scan($input): ScanOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, ], 'usesEndpointDiscovery' => true])); return new ScanOutput($response, $this, $input); @@ -905,6 +922,7 @@ public function tableNotExists($input): TableNotExistsWaiter * @throws ProvisionedThroughputExceededException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException * @throws TransactionCanceledException * @throws TransactionInProgressException */ @@ -917,6 +935,7 @@ public function transactWriteItems($input): TransactWriteItemsOutput 'ProvisionedThroughputExceededException' => ProvisionedThroughputExceededException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, 'TransactionCanceledException' => TransactionCanceledException::class, 'TransactionInProgressException' => TransactionInProgressException::class, ], 'usesEndpointDiscovery' => true])); @@ -960,6 +979,7 @@ public function transactWriteItems($input): TransactWriteItemsOutput * @throws ReplicatedWriteConflictException * @throws RequestLimitExceededException * @throws ResourceNotFoundException + * @throws ThrottlingException * @throws TransactionConflictException */ public function updateItem($input): UpdateItemOutput @@ -973,6 +993,7 @@ public function updateItem($input): UpdateItemOutput 'ReplicatedWriteConflictException' => ReplicatedWriteConflictException::class, 'RequestLimitExceeded' => RequestLimitExceededException::class, 'ResourceNotFoundException' => ResourceNotFoundException::class, + 'ThrottlingException' => ThrottlingException::class, 'TransactionConflictException' => TransactionConflictException::class, ], 'usesEndpointDiscovery' => true])); diff --git a/src/Service/DynamoDb/src/Exception/ProvisionedThroughputExceededException.php b/src/Service/DynamoDb/src/Exception/ProvisionedThroughputExceededException.php index 7cf6fa002..f09abe285 100644 --- a/src/Service/DynamoDb/src/Exception/ProvisionedThroughputExceededException.php +++ b/src/Service/DynamoDb/src/Exception/ProvisionedThroughputExceededException.php @@ -3,15 +3,64 @@ namespace AsyncAws\DynamoDb\Exception; use AsyncAws\Core\Exception\Http\ClientException; +use AsyncAws\DynamoDb\ValueObject\ThrottlingReason; +use Symfony\Contracts\HttpClient\ResponseInterface; /** - * Your request rate is too high. The Amazon Web Services SDKs for DynamoDB automatically retry requests that receive - * this exception. Your request is eventually successful, unless your retry queue is too large to finish. Reduce the - * frequency of requests and use exponential backoff. For more information, go to Error Retries and Exponential Backoff - * [^1] in the *Amazon DynamoDB Developer Guide*. + * The request was denied due to request throttling. For detailed information about why the request was throttled and + * the ARN of the impacted resource, find the ThrottlingReason [^1] field in the returned exception. The Amazon Web + * Services SDKs for DynamoDB automatically retry requests that receive this exception. Your request is eventually + * successful, unless your retry queue is too large to finish. Reduce the frequency of requests and use exponential + * backoff. For more information, go to Error Retries and Exponential Backoff [^2] in the *Amazon DynamoDB Developer + * Guide*. * - * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff + * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ThrottlingReason.html + * [^2]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff */ final class ProvisionedThroughputExceededException extends ClientException { + /** + * A list of ThrottlingReason [^1] that provide detailed diagnostic information about why the request was throttled. + * + * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ThrottlingReason.html + * + * @var ThrottlingReason[] + */ + private $throttlingReasons; + + /** + * @return ThrottlingReason[] + */ + public function getThrottlingReasons(): array + { + return $this->throttlingReasons; + } + + protected function populateResult(ResponseInterface $response): void + { + $data = $response->toArray(false); + + $this->throttlingReasons = empty($data['ThrottlingReasons']) ? [] : $this->populateResultThrottlingReasonList($data['ThrottlingReasons']); + } + + private function populateResultThrottlingReason(array $json): ThrottlingReason + { + return new ThrottlingReason([ + 'reason' => isset($json['reason']) ? (string) $json['reason'] : null, + 'resource' => isset($json['resource']) ? (string) $json['resource'] : null, + ]); + } + + /** + * @return ThrottlingReason[] + */ + private function populateResultThrottlingReasonList(array $json): array + { + $items = []; + foreach ($json as $item) { + $items[] = $this->populateResultThrottlingReason($item); + } + + return $items; + } } diff --git a/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php b/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php index 355ffd655..1c7fb9e84 100644 --- a/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php +++ b/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php @@ -3,13 +3,61 @@ namespace AsyncAws\DynamoDb\Exception; use AsyncAws\Core\Exception\Http\ClientException; +use AsyncAws\DynamoDb\ValueObject\ThrottlingReason; +use Symfony\Contracts\HttpClient\ResponseInterface; /** - * Throughput exceeds the current throughput quota for your account. Please contact Amazon Web ServicesSupport [^1] to - * request a quota increase. + * Throughput exceeds the current throughput quota for your account. For detailed information about why the request was + * throttled and the ARN of the impacted resource, find the ThrottlingReason [^1] field in the returned exception. + * Contact Amazon Web ServicesSupport [^2] to request a quota increase. * - * [^1]: https://aws.amazon.com/support + * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ThrottlingReason.html + * [^2]: https://aws.amazon.com/support */ final class RequestLimitExceededException extends ClientException { + /** + * A list of ThrottlingReason [^1] that provide detailed diagnostic information about why the request was throttled. + * + * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ThrottlingReason.html + * + * @var ThrottlingReason[] + */ + private $throttlingReasons; + + /** + * @return ThrottlingReason[] + */ + public function getThrottlingReasons(): array + { + return $this->throttlingReasons; + } + + protected function populateResult(ResponseInterface $response): void + { + $data = $response->toArray(false); + + $this->throttlingReasons = empty($data['ThrottlingReasons']) ? [] : $this->populateResultThrottlingReasonList($data['ThrottlingReasons']); + } + + private function populateResultThrottlingReason(array $json): ThrottlingReason + { + return new ThrottlingReason([ + 'reason' => isset($json['reason']) ? (string) $json['reason'] : null, + 'resource' => isset($json['resource']) ? (string) $json['resource'] : null, + ]); + } + + /** + * @return ThrottlingReason[] + */ + private function populateResultThrottlingReasonList(array $json): array + { + $items = []; + foreach ($json as $item) { + $items[] = $this->populateResultThrottlingReason($item); + } + + return $items; + } } diff --git a/src/Service/DynamoDb/src/Exception/ThrottlingException.php b/src/Service/DynamoDb/src/Exception/ThrottlingException.php new file mode 100644 index 000000000..eaf5cfe68 --- /dev/null +++ b/src/Service/DynamoDb/src/Exception/ThrottlingException.php @@ -0,0 +1,61 @@ +throttlingReasons; + } + + protected function populateResult(ResponseInterface $response): void + { + $data = $response->toArray(false); + + $this->throttlingReasons = empty($data['throttlingReasons']) ? [] : $this->populateResultThrottlingReasonList($data['throttlingReasons']); + } + + private function populateResultThrottlingReason(array $json): ThrottlingReason + { + return new ThrottlingReason([ + 'reason' => isset($json['reason']) ? (string) $json['reason'] : null, + 'resource' => isset($json['resource']) ? (string) $json['resource'] : null, + ]); + } + + /** + * @return ThrottlingReason[] + */ + private function populateResultThrottlingReasonList(array $json): array + { + $items = []; + foreach ($json as $item) { + $items[] = $this->populateResultThrottlingReason($item); + } + + return $items; + } +} diff --git a/src/Service/DynamoDb/src/ValueObject/ThrottlingReason.php b/src/Service/DynamoDb/src/ValueObject/ThrottlingReason.php new file mode 100644 index 000000000..478b00b05 --- /dev/null +++ b/src/Service/DynamoDb/src/ValueObject/ThrottlingReason.php @@ -0,0 +1,86 @@ +reason = $input['reason'] ?? null; + $this->resource = $input['resource'] ?? null; + } + + /** + * @param array{ + * reason?: null|string, + * resource?: null|string, + * }|ThrottlingReason $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getReason(): ?string + { + return $this->reason; + } + + public function getResource(): ?string + { + return $this->resource; + } +}