Skip to content

Commit

Permalink
Fix error decoding of string body (#31265)
Browse files Browse the repository at this point in the history
  • Loading branch information
kldtz authored Sep 1, 2023
1 parent c6be14f commit 87c886d
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 9 deletions.
6 changes: 6 additions & 0 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,12 @@
"specifed"
]
},
{
"filename": "sdk/tables/azure-data-tables/CHANGELOG.md",
"words": [
"kldtz"
]
},
{
"filename": "sdk/tables/test-resources.json",
"words": [
Expand Down
5 changes: 2 additions & 3 deletions sdk/tables/azure-data-tables/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# Release History

## 12.4.4 (Unreleased)
## 12.4.4 (2023-09-12)

### Features Added
* Enabled to specify resource type `container` in account SAS access.

### Breaking Changes

### Bugs Fixed
* Fixed a bug when submitting transactions with an empty operation list. ([#31471](https://github.com/Azure/azure-sdk-for-python/issues/31471))
* Fixed a bug when decoding response body in string type. Thanks @kldtz for the contribution! ([#31265](https://github.com/Azure/azure-sdk-for-python/pull/31265))

### Other Changes
* Bumped minimum dependency on `azure-core` to `>=1.27.1`. ([#28918](https://github.com/Azure/azure-sdk-for-python/issues/28918))
Expand Down
4 changes: 4 additions & 0 deletions sdk/tables/azure-data-tables/azure/data/tables/_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,17 @@ def _decode_error(response, error_message=None, error_type=None, **kwargs): # p
additional_data[info.tag] = info.text
else:
if error_body:
# Attempt to parse from XML element
for info in error_body.iter():
if info.tag.lower().find("code") != -1:
error_code = info.text
elif info.tag.lower().find("message") != -1:
error_message = info.text
else:
additional_data[info.tag] = info.text
except AttributeError:
# Response body wasn't XML, give up trying to parse
error_message = str(error_body)
except DecodeError:
pass

Expand Down
44 changes: 43 additions & 1 deletion sdk/tables/azure-data-tables/tests/test_table_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
from datetime import datetime, timedelta
import os
import pytest

from functools import partial
from requests import Response
from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy, set_custom_default_matcher

from azure.core import MatchConditions
from azure.core.pipeline import PipelineRequest, PipelineResponse
from azure.core.pipeline.policies import HTTPPolicy
from azure.core.pipeline.transport._requests_basic import RequestsTransportResponse
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
from azure.core.exceptions import ResourceNotFoundError, ClientAuthenticationError, HttpResponseError
from azure.data.tables import (
Expand All @@ -30,6 +33,7 @@
TableClient,
)
from azure.data.tables._constants import DEFAULT_STORAGE_ENDPOINT_SUFFIX
from azure.identity import DefaultAzureCredential
from _shared.testcase import TableTestCase
from preparers import tables_decorator

Expand Down Expand Up @@ -1243,3 +1247,41 @@ def test_batch_url_for_cosmos_emulator(self):
assert table.scheme == "http"
with pytest.raises(RequestCorrect):
table.submit_transaction(self.batch)

def test_decode_string_body(self):
def patch_run(request: PipelineRequest, **kwargs) -> PipelineResponse:
response = Response()
response.status_code = 405
response._content = b"<!DOCTYPE html><html><head><title>UnsupportedHttpVerb</title></head><body><h1>The resource doesn't support specified Http Verb.</h1><p><ul><li>HttpStatusCode: 405</li><li>ErrorCode: UnsupportedHttpVerb</li><li>RequestId : 98adf858-a01e-0071-2580-bfe811000000</li><li>TimeStamp : 2023-07-26T05:19:26.9825582Z</li></ul></p></body></html>"
response.url = "https://<storage>.z6.web.core.windows.net/$batch"
response.headers = {"x-ms-error-code": "UnsupportedHttpVerb", "content-type": "text/html"}
return PipelineResponse(
http_request=None,
http_response=RequestsTransportResponse(
requests_response=response,
request=None,
),
context=None,
)

with TableClient(
endpoint="https://<storage>.z6.web.core.windows.net/",
credential=DefaultAzureCredential(),
table_name="syncenabled",
) as client:
client._client._client._pipeline.run = partial(patch_run)
with pytest.raises(HttpResponseError) as ex:
client.submit_transaction(
[
(
"upsert",
{
"PartitionKey": "test-partition",
"RowKey": "test-key",
"name": "test-name",
},
)
]
)
assert ex.value.status_code == 405
assert ex.value.error_code == "UnsupportedHttpVerb"
52 changes: 47 additions & 5 deletions sdk/tables/azure-data-tables/tests/test_table_batch_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

import pytest

from datetime import datetime, timedelta
import os

import pytest
from functools import partial
from requests import Response
from devtools_testutils import AzureRecordedTestCase, set_custom_default_matcher
from devtools_testutils.aio import recorded_by_proxy_async

from azure.core import MatchConditions
from azure.core.pipeline import PipelineRequest, PipelineResponse
from azure.core.pipeline.policies import AsyncHTTPPolicy
from azure.core.pipeline.transport._requests_asyncio import AsyncioRequestsTransportResponse
from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import ResourceNotFoundError, ClientAuthenticationError, HttpResponseError
from azure.data.tables.aio import TableServiceClient, TableClient
Expand All @@ -32,7 +33,7 @@
TableErrorCode,
)
from azure.data.tables._constants import DEFAULT_STORAGE_ENDPOINT_SUFFIX

from azure.identity.aio import DefaultAzureCredential
from _shared.asynctestcase import AsyncTableTestCase
from async_preparers import tables_decorator_async

Expand Down Expand Up @@ -1178,3 +1179,44 @@ async def test_batch_url_for_cosmos_emulator(self):
assert table.scheme == "http"
with pytest.raises(RequestCorrect):
await table.submit_transaction(self.batch)

@pytest.mark.asyncio
async def test_decode_string_body(self):
async def patch_run(request: PipelineRequest, **kwargs) -> PipelineResponse:
response = Response()
response.status_code = 405
response._content = b"<!DOCTYPE html><html><head><title>UnsupportedHttpVerb</title></head><body><h1>The resource doesn't support specified Http Verb.</h1><p><ul><li>HttpStatusCode: 405</li><li>ErrorCode: UnsupportedHttpVerb</li><li>RequestId : 98adf858-a01e-0071-2580-bfe811000000</li><li>TimeStamp : 2023-07-26T05:19:26.9825582Z</li></ul></p></body></html>"
response.url = "https://<storage>.z6.web.core.windows.net/$batch"
response.headers = {"x-ms-error-code": "UnsupportedHttpVerb", "content-type": "text/html"}
return PipelineResponse(
http_request=None,
http_response=AsyncioRequestsTransportResponse(
requests_response=response,
request=None,
),
context=None,
)

client = TableClient(
endpoint=self.account_url(self.tables_storage_account_name, "table"),
credential=DefaultAzureCredential(
name=self.tables_storage_account_name, key=self.tables_primary_storage_account_key
),
table_name="syncenabled",
)
client._client._client._pipeline.run = partial(patch_run)
with pytest.raises(HttpResponseError) as ex:
await client.submit_transaction(
[
(
"upsert",
{
"PartitionKey": "test-partition",
"RowKey": "test-key",
"name": "test-name",
},
)
]
)
assert ex.value.status_code == 405
assert ex.value.error_code == "UnsupportedHttpVerb"

0 comments on commit 87c886d

Please sign in to comment.