Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error decoding of string body #31265

Merged
merged 15 commits into from
Sep 1, 2023
Merged

Fix error decoding of string body #31265

merged 15 commits into from
Sep 1, 2023

Conversation

kldtz
Copy link
Contributor

@kldtz kldtz commented Jul 24, 2023

If error_body is a string (which may happen), calling iter() on it will result in: AttributeError: 'str' object has no attribute 'iter'. Use the body as message instead.

This error appeared when I configured a wrong endpoint that returned an HTML error response. The AttributeError was hiding the actual error, which made debugging the problem harder.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

If error_body is a string, calling iter() on it will result in: AttributeError: 'str' object has no attribute 'iter'.
Use the body as message instead.
@github-actions github-actions bot added Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. Tables labels Jul 24, 2023
@github-actions
Copy link

Thank you for your contribution @kldtz! We will review the pull request and get back to you soon.

@annatisch
Copy link
Member

Thanks so much @kldtz!
Could you please provide more details (e.g. a code snippet) on the scenario where you encountered this error?
Then we can add a test to repro this so that the new behaviour can be properly accounted for to prevent any future regressions :)

@YalinLi0312 YalinLi0312 added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Jul 24, 2023
@kldtz
Copy link
Contributor Author

kldtz commented Jul 25, 2023

Hi @annatisch, sure:

client = TableClient(
    # wrong endpoint that responds with HTML
    endpoint="https://<storage>.z6.web.core.windows.net/",
    credential=DefaultAzureCredential(),
    table_name="table-name"
)
client.submit_transaction([
    (
        "upsert",
        {
            "PartitionKey": "test-partition",
            "RowKey": "test-key",
            "name": "test-name",
        },
    )
])

I just saw that in other places _process_table_error is called, which deals with the AttributeError, but _batch_send calls _decode_error directly. Catching the AttributeError and raising the original error would be an alternative fix.

@YalinLi0312
Copy link

Hi @kldtz , I got ServiceRequestError instead. Here's the code snippet I tried:

client = TableClient(
            # wrong endpoint that responds with HTML
            endpoint="https://<tables_storage_account_name>.z6.web.core.windows.net/",
            credential=DefaultAzureCredential(),
            table_name="table-name"
        )
        with pytest.raises(ServiceRequestError) as ex:
            client.submit_transaction([
                (
                    "upsert",
                    {
                        "PartitionKey": "test-partition",
                        "RowKey": "test-key",
                        "name": "test-name",
                    },
                )
            ])
        assert "Failed to establish a new connection" in str(ex.value)

Do you know if I missed anything?

@kldtz
Copy link
Contributor Author

kldtz commented Jul 26, 2023

Hi @YalinLi0312 ,

you can try this snippet, where I monkey-patched the run method:

from functools import partial
from typing import Any

from azure.core.pipeline import HTTPRequestType, PipelineResponse, HTTPResponseType
from azure.core.pipeline.transport._requests_basic import RequestsTransportResponse
from azure.data.tables import TableClient
from azure.identity import DefaultAzureCredential
from requests import Response


def patch_run(self, request: HTTPRequestType, **kwargs: Any) -> PipelineResponse[HTTPRequestType, HTTPResponseType]:
    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,
    )


if __name__ == '__main__':
    client = TableClient(
        endpoint="https://<storage>.z6.web.core.windows.net/",
        credential=DefaultAzureCredential(),
        table_name="syncenabled"
    )
    client._client._client._pipeline.run = partial(patch_run, client)
    client.submit_transaction([
        (
            "upsert",
            {
                "PartitionKey": "test-partition",
                "RowKey": "test-key",
                "name": "test-name",
            },
        )
    ])

If the content type is text/html the method deserialize_from_http_generics returns a string, which results in the AttributeError. If you're not able to reproduce it, feel free to close the PR.

@YalinLi0312
Copy link

Hi @YalinLi0312 ,

you can try this snippet, where I monkey-patched the run method:

from functools import partial
from typing import Any

from azure.core.pipeline import HTTPRequestType, PipelineResponse, HTTPResponseType
from azure.core.pipeline.transport._requests_basic import RequestsTransportResponse
from azure.data.tables import TableClient
from azure.identity import DefaultAzureCredential
from requests import Response


def patch_run(self, request: HTTPRequestType, **kwargs: Any) -> PipelineResponse[HTTPRequestType, HTTPResponseType]:
    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,
    )


if __name__ == '__main__':
    client = TableClient(
        endpoint="https://<storage>.z6.web.core.windows.net/",
        credential=DefaultAzureCredential(),
        table_name="syncenabled"
    )
    client._client._client._pipeline.run = partial(patch_run, client)
    client.submit_transaction([
        (
            "upsert",
            {
                "PartitionKey": "test-partition",
                "RowKey": "test-key",
                "name": "test-name",
            },
        )
    ])

If the content type is text/html the method deserialize_from_http_generics returns a string, which results in the AttributeError. If you're not able to reproduce it, feel free to close the PR.

Thank you, I'll try on it!

@YalinLi0312 YalinLi0312 removed the needs-author-feedback Workflow: More information is needed from author to address the issue. label Aug 1, 2023
@YalinLi0312
Copy link

Hi @kldtz , I did reproduce the error with the sample you provided. Can you assign me the permission to edit on your branch? I want to add some tests.

@YalinLi0312 YalinLi0312 added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Aug 4, 2023
@kldtz
Copy link
Contributor Author

kldtz commented Aug 5, 2023

@YalinLi0312 As far as I can see, you already have edit rights.

@YalinLi0312
Copy link

@YalinLi0312 As far as I can see, you already have edit rights.

It failed due to lacking permission when I tried. Can you assign me the permission? Or do you mind me fixing it in another PR?

@kldtz
Copy link
Contributor Author

kldtz commented Aug 8, 2023

"Allow edits by maintainers" is checked. Not sure what else I can do. You can fix it in another PR.

@kldtz
Copy link
Contributor Author

kldtz commented Aug 20, 2023

@microsoft-github-policy-service agree

Copy link
Member

@annatisch annatisch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kldtz, @YalinLi0312!

@YalinLi0312 YalinLi0312 enabled auto-merge (squash) September 1, 2023 02:06
@YalinLi0312 YalinLi0312 merged commit 87c886d into Azure:main Sep 1, 2023
@YalinLi0312
Copy link

Hi @kldtz - we'll prepare a release with this fix on 9/12/2023, please give it a try and welcome to any feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-author-feedback Workflow: More information is needed from author to address the issue. Tables
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants