Repository: getmoto/moto

Issue:
[DynamoDb] All Errors are deserialized as DynamoDbException in JAVA SDK
Using MotoServer to test Java based services. This Service creates the DynamoDb table if it doesn't exist, ie, on ResourceNotFoundException, table is created.
When using the MotoServer, We get response

```json
{"__type": "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException", "message": "Requested resource not found"}
```
When this is deserialized in java sdk, as there is no error-code for  `com.amazonaws.dynamodb.v20111205#ResourceNotFoundException` hence, All the error is wrapped, and returned as `DynamoDbException`

With other services, similar issue is not occurring. The issue exists for version>=3.1.5, and seems to be introduced by this https://github.com/getmoto/moto/pull/5012
Tried using <=3.1.4 to overcome this problem, but ended up encountering another bug related to Glue, which is fixed in the recent version. So, unable to use the older versions as a workaround

Could you please share reason behind the error message? would it be possible to have error message compatible with Java SDKs too?



Discussion:
Thanks for raising this @munendrasn - marking it as a bug.

#5012 was an attempt to streamline all error messages - but because we only fully test against the Python SDK, which is more forgiving, we never realized it was broken. Will raise a PR shortly.
@bblommers 
Thanks for the quick fix. 

I did a quick test with `4.1.4.dev29` but encountering the same issue with Java SDK (2.17.257), ie, even though the error message proper, `Requested resource not found: Table: e9f18915466b4516adf373ae754a19ed not found` but error/exception of type DynamoDbException instead of ResourceNotFoundException

I think having the error prefix is causing the issue. Based on the description from the PR https://github.com/getmoto/moto/pull/5997#issue-1601974124, it seems prefix is required for python sdk. Is this the correct understanding?

@munendrasn I actually tested this against AWS, and this format is exactly what AWS returns. So I assumed the Java SDK would be OK with it.
I'll have another look.
Can you try this again with moto >= 4.1.4.dev36 @munendrasn? 

We now also have some Java tests as part of our build pipeline, so if you do come across a scenario that still fails, feel free to provide some sample Java code - we can make that part of our tests as well.
@bblommers 
I did one round of testing with 4.1.4.dev36, working as expected. Thanks for the fix.

While testing encountered another issue with Glue. CreateTable is working as expected. GetTable post successful UpdateTable still returns the older version. This issue is not specific to Java SDK

Based on the initial analysis, this issue doesn't exist in released, and seems to be related PR https://github.com/getmoto/moto/pull/5968, I think when converting table to dict https://github.com/getmoto/moto/blob/0e24b281eb12825706fd9088e8b4cd4e295af443/moto/glue/responses.py#L63, we might need to use the current version, or update the `get_table` behavior to use current_version if version is not passed as arg to `as_dict()`
Same issue might be occurring for `getTables` based on initial look, but this is not tested

Kindly, let me know if additional analysis, or test is required
@munendrasn If you can share a test with the expected behaviour, that would be useful. I think I understand the problem, but a test would be good to verify my understanding.

Resolving patch:
diff --git a/moto/glue/models.py b/moto/glue/models.py
--- a/moto/glue/models.py
+++ b/moto/glue/models.py
@@ -840,7 +840,8 @@ def get_version(self, ver):
     def delete_version(self, version_id):
         self.versions.pop(version_id)
 
-    def as_dict(self, version=1):
+    def as_dict(self, version=None):
+        version = version or self._current_version
         obj = {
             "DatabaseName": self.database_name,
             "Name": self.name,


Test patch:
diff --git a/tests/test_glue/test_datacatalog.py b/tests/test_glue/test_datacatalog.py
--- a/tests/test_glue/test_datacatalog.py
+++ b/tests/test_glue/test_datacatalog.py
@@ -319,6 +319,11 @@ def test_get_table_versions():
     helpers.create_table(client, database_name, table_name, table_input)
     version_inputs["1"] = table_input
 
+    # Get table should retrieve the first version
+    table = client.get_table(DatabaseName=database_name, Name=table_name)["Table"]
+    table["StorageDescriptor"]["Columns"].should.equal([])
+    table["VersionId"].should.equal("1")
+
     columns = [{"Name": "country", "Type": "string"}]
     table_input = helpers.create_table_input(database_name, table_name, columns=columns)
     helpers.update_table(client, database_name, table_name, table_input)
@@ -354,6 +359,15 @@ def test_get_table_versions():
     ver["Table"]["Name"].should.equal(table_name)
     ver["Table"]["StorageDescriptor"]["Columns"].should.equal(columns)
 
+    # get_table should retrieve the latest version
+    table = client.get_table(DatabaseName=database_name, Name=table_name)["Table"]
+    table["StorageDescriptor"]["Columns"].should.equal(columns)
+    table["VersionId"].should.equal("3")
+
+    table = client.get_tables(DatabaseName=database_name)["TableList"][0]
+    table["StorageDescriptor"]["Columns"].should.equal(columns)
+    table["VersionId"].should.equal("3")
+
 
 @mock_glue
 def test_get_table_version_not_found():