Repository: getmoto/moto
Pull request #6449 (2023-06-27 10:54:04)

DynamoDB: correct no table error
Closes https://github.com/getmoto/moto/issues/6441


Patch:
diff --git a/moto/dynamodb/responses.py b/moto/dynamodb/responses.py
index bd805c0ea..1adc7430b 100644
--- a/moto/dynamodb/responses.py
+++ b/moto/dynamodb/responses.py
@@ -13,7 +13,6 @@ from moto.dynamodb.parsing.reserved_keywords import ReservedKeywords
 from .exceptions import (
     MockValidationException,
     ResourceNotFoundException,
-    ConditionalCheckFailed,
 )
 from moto.dynamodb.models import dynamodb_backends, Table, DynamoDBBackend
 from moto.dynamodb.models.utilities import dynamo_json_dump
@@ -806,12 +805,7 @@ class DynamoHandler(BaseResponse):
         if return_values not in ("ALL_OLD", "NONE"):
             raise MockValidationException("Return values set to invalid value")
 
-        try:
-            self.dynamodb_backend.get_table(name)
-        except ResourceNotFoundException:
-            raise ConditionalCheckFailed(
-                "A condition specified in the operation could not be evaluated."
-            )
+        self.dynamodb_backend.get_table(name)
 
         # Attempt to parse simple ConditionExpressions into an Expected
         # expression
diff --git a/moto/stepfunctions/exceptions.py b/moto/stepfunctions/exceptions.py
index b7e449a54..8467daf33 100644
--- a/moto/stepfunctions/exceptions.py
+++ b/moto/stepfunctions/exceptions.py
@@ -45,3 +45,18 @@ class ResourceNotFound(AWSError):
 
     def __init__(self, arn: str):
         super().__init__(f"Resource not found: '{arn}'")
+
+
+class ValidationException(AWSError):
+    TYPE = "ValidationException"
+
+    def __init__(self, msg: str):
+        super().__init__(msg)
+
+
+class NameTooLongException(ValidationException):
+    def __init__(self, name: str):
+        super().__init__(
+            f"1 validation error detected: Value '{name}' at 'name' "
+            "failed to satisfy constraint: Member must have length less than or equal to 80"
+        )
diff --git a/moto/stepfunctions/models.py b/moto/stepfunctions/models.py
index 3df09e648..e007d604e 100644
--- a/moto/stepfunctions/models.py
+++ b/moto/stepfunctions/models.py
@@ -15,6 +15,7 @@ from .exceptions import (
     InvalidName,
     ResourceNotFound,
     StateMachineDoesNotExist,
+    NameTooLongException,
 )
 from .utils import api_to_cfn_tags, cfn_to_api_tags, PAGINATION_MODEL
 from moto import settings
@@ -533,6 +534,8 @@ class StepFunctionBackend(BaseBackend):
     def start_execution(
         self, state_machine_arn: str, name: str, execution_input: str
     ) -> Execution:
+        if name:
+            self._validate_name(name)
         state_machine = self.describe_state_machine(state_machine_arn)
         return state_machine.start_execution(
             region_name=self.region_name,
@@ -634,6 +637,9 @@ class StepFunctionBackend(BaseBackend):
         if any(name.find(char) >= 0 for char in self.invalid_unicodes_for_name):
             raise InvalidName("Invalid Name: '" + name + "'")
 
+        if len(name) > 80:
+            raise NameTooLongException(name)
+
     def _validate_role_arn(self, role_arn: str) -> None:
         self._validate_arn(
             arn=role_arn,


Test patch:
diff --git a/tests/test_dynamodb/test_dynamodb.py b/tests/test_dynamodb/test_dynamodb.py
index 8de5cc32f..3b53e3772 100644
--- a/tests/test_dynamodb/test_dynamodb.py
+++ b/tests/test_dynamodb/test_dynamodb.py
@@ -1753,6 +1753,38 @@ def test_delete_item():
     assert response["Count"] == 0
 
 
+@mock_dynamodb
+def test_delete_item_error():
+    # Setup
+    client = boto3.resource("dynamodb", region_name="us-east-1")
+    # Create the DynamoDB table.
+    client.create_table(
+        TableName="test1",
+        AttributeDefinitions=[
+            {"AttributeName": "client", "AttributeType": "S"},
+            {"AttributeName": "app", "AttributeType": "S"},
+        ],
+        KeySchema=[
+            {"AttributeName": "client", "KeyType": "HASH"},
+            {"AttributeName": "app", "KeyType": "RANGE"},
+        ],
+        BillingMode="PAY_PER_REQUEST",
+    )
+    table = client.Table("test1")
+    table.delete()
+
+    # Execute
+    with pytest.raises(ClientError) as ex:
+        table.delete_item(
+            Key={"client": "client1", "app": "app1"},
+        )
+
+    # Verify
+    err = ex.value.response["Error"]
+    assert err["Code"] == "ResourceNotFoundException"
+    assert err["Message"] == "Requested resource not found"
+
+
 @mock_dynamodb
 def test_describe_limits():
     client = boto3.client("dynamodb", region_name="eu-central-1")
diff --git a/tests/test_dynamodb/test_dynamodb_table_without_range_key.py b/tests/test_dynamodb/test_dynamodb_table_without_range_key.py
index caadf8bd6..780f8f963 100644
--- a/tests/test_dynamodb/test_dynamodb_table_without_range_key.py
+++ b/tests/test_dynamodb/test_dynamodb_table_without_range_key.py
@@ -197,11 +197,9 @@ def test_delete_item_with_undeclared_table():
             TableName="messages", Key={"forum_name": {"S": "LOLCat Forum"}}
         )
 
-    ex.value.response["Error"]["Code"].should.equal("ConditionalCheckFailedException")
-    ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
-    ex.value.response["Error"]["Message"].should.equal(
-        "A condition specified in the operation could not be evaluated."
-    )
+    assert ex.value.response["Error"]["Code"] == "ResourceNotFoundException"
+    assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
+    assert ex.value.response["Error"]["Message"] == "Requested resource not found"
 
 
 @mock_dynamodb
diff --git a/tests/test_stepfunctions/test_stepfunctions.py b/tests/test_stepfunctions/test_stepfunctions.py
index 04b129702..70d8faa11 100644
--- a/tests/test_stepfunctions/test_stepfunctions.py
+++ b/tests/test_stepfunctions/test_stepfunctions.py
@@ -959,5 +959,53 @@ def test_state_machine_get_execution_history_contains_expected_failure_events_wh
     assert exc["status"] == "FAILED"
 
 
+@mock_stepfunctions
+def test_state_machine_name_limits():
+    # Setup
+    client = boto3.client("stepfunctions", region_name=region)
+    long_name = "t" * 81
+
+    # Execute
+    with pytest.raises(ClientError) as exc:
+        client.create_state_machine(
+            name=long_name,
+            definition=simple_definition,
+            roleArn=_get_default_role(),
+        )
+
+    # Verify
+    assert exc.value.response["Error"]["Code"] == "ValidationException"
+    assert (
+        exc.value.response["Error"]["Message"]
+        == f"1 validation error detected: Value '{long_name}' at 'name' failed to satisfy constraint: "
+        "Member must have length less than or equal to 80"
+    )
+
+
+@mock_stepfunctions
+def test_state_machine_execution_name_limits():
+    # Setup
+    client = boto3.client("stepfunctions", region_name=region)
+    machine_name = "test_name"
+    long_name = "t" * 81
+    resp = client.create_state_machine(
+        name=machine_name,
+        definition=simple_definition,
+        roleArn=_get_default_role(),
+    )
+
+    # Execute
+    with pytest.raises(ClientError) as exc:
+        client.start_execution(name=long_name, stateMachineArn=resp["stateMachineArn"])
+
+    # Verify
+    assert exc.value.response["Error"]["Code"] == "ValidationException"
+    assert (
+        exc.value.response["Error"]["Message"]
+        == f"1 validation error detected: Value '{long_name}' at 'name' failed to satisfy constraint: "
+        "Member must have length less than or equal to 80"
+    )
+
+
 def _get_default_role():
     return "arn:aws:iam::" + ACCOUNT_ID + ":role/unknown_sf_role"