Repository: getmoto/moto

Issue:
Mocked DynamoDB throws wrong error when table doesn't exist
## Impact

I am unable to use moto to accurately test code that detects when a DynamoDB table is not replicated in the current region

## Reproduce

```python
from moto import mock_dynamodb2
import boto3

@mock_dynamodb2
def repro():
  client = boto3.client('dynamodb', 'us-east-1')
  result = client.get_item(TableName='foo', Key={'site-id': {'S': 'foo'}})
```

## Expected result

`ResourceNotFound` raised. Here's the stack trace from boto3 for a live API request:

```
  File "test.py", line 3, in <module>
    client.get_item(TableName='foo', Key={'site-id': {'S': 'foo'}})
  File "/usr/local/lib/python3.9/site-packages/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python3.9/site-packages/botocore/client.py", line 676, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the GetItem operation: Requested resource not found
```

## Actual result

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "venv/lib/python3.9/site-packages/moto/core/models.py", line 100, in wrapper
    result = func(*args, **kwargs)
  File "<stdin>", line 4, in test_my_model_save
  File "venv/lib/python3.9/site-packages/botocore/client.py", line 337, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "venv/lib/python3.9/site-packages/botocore/client.py", line 656, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the GetItem operation: Validation Exception
```

## Versions
- Python 3.9.0
- Moto 1.3.16
- botocore 1.18.0



Discussion:
Thanks for raising this @max-reify. Doesn't look like we're explicitly checking for this scenario yet, so marking it as an enhancement

Resolving patch:
diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py
--- a/moto/dynamodb2/responses.py
+++ b/moto/dynamodb2/responses.py
@@ -349,6 +349,12 @@ def batch_write_item(self):
 
     def get_item(self):
         name = self.body["TableName"]
+        table = self.dynamodb_backend.get_table(name)
+        if table is None:
+            return self.error(
+                "com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
+                "Requested resource not found",
+            )
         key = self.body["Key"]
         projection_expression = self.body.get("ProjectionExpression")
         expression_attribute_names = self.body.get("ExpressionAttributeNames", {})


Test patch:
diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py
--- a/tests/test_dynamodb2/test_dynamodb.py
+++ b/tests/test_dynamodb2/test_dynamodb.py
@@ -5698,3 +5698,12 @@ def test_update_item_add_to_list_using_legacy_attribute_updates():
 
     resp = table.get_item(Key={"id": "list_add"})
     resp["Item"]["attr"].should.equal(["a", "b", "c", "d", "e"])
+
+
+@mock_dynamodb2
+def test_get_item_for_non_existent_table_raises_error():
+    client = boto3.client("dynamodb", "us-east-1")
+    with pytest.raises(ClientError) as ex:
+        client.get_item(TableName="non-existent", Key={"site-id": {"S": "foo"}})
+    ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
+    ex.value.response["Error"]["Message"].should.equal("Requested resource not found")