From 66a30512c3c1d26c9b99e191122d72387441d3d3 Mon Sep 17 00:00:00 2001 From: Krista Pratico Date: Mon, 20 Jul 2020 16:07:54 -0700 Subject: [PATCH 1/5] include error code for errors that occur during polling --- .../azure/ai/formrecognizer/_polling.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py index f1ef5267a283..4ff4fd285a54 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py @@ -5,7 +5,7 @@ # ------------------------------------ from typing import TYPE_CHECKING -from azure.core.exceptions import HttpResponseError +from azure.core.exceptions import HttpResponseError, ODataV4Format from azure.core.polling.base_polling import ( LocationPolling, OperationResourcePolling, @@ -18,9 +18,10 @@ def raise_error(response, errors, message): - for err in errors: - message += "({}) {}\n".format(err["code"], err["message"]) - raise HttpResponseError(message=message, response=response) + message += "({}) {}\n".format(errors[0]["code"], errors[0]["message"]) + error = HttpResponseError(message=message, response=response) + error.error = ODataV4Format(errors[0]) + raise error class TrainingPolling(LocationPolling): From 4bf7d6318301e7623584943e94771702017b1d97 Mon Sep 17 00:00:00 2001 From: Krista Pratico Date: Mon, 20 Jul 2020 16:23:08 -0700 Subject: [PATCH 2/5] fix error message --- .../azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py index 4ff4fd285a54..47b72ba4f63f 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py @@ -21,6 +21,7 @@ def raise_error(response, errors, message): message += "({}) {}\n".format(errors[0]["code"], errors[0]["message"]) error = HttpResponseError(message=message, response=response) error.error = ODataV4Format(errors[0]) + error.error.message = message raise error From 58f6fd7b4d4e8e1483b84b6218ad8648350d22ee Mon Sep 17 00:00:00 2001 From: Krista Pratico Date: Mon, 20 Jul 2020 17:17:20 -0700 Subject: [PATCH 3/5] update tests to check for presence of error code/message --- .../azure/ai/formrecognizer/_polling.py | 7 +++---- .../azure-ai-formrecognizer/tests/test_copy_model.py | 5 ++++- .../azure-ai-formrecognizer/tests/test_copy_model_async.py | 5 ++++- .../tests/test_custom_forms_from_url.py | 5 ++++- .../tests/test_custom_forms_from_url_async.py | 5 ++++- .../azure-ai-formrecognizer/tests/test_training.py | 5 ++++- .../azure-ai-formrecognizer/tests/test_training_async.py | 5 ++++- 7 files changed, 27 insertions(+), 10 deletions(-) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py index 47b72ba4f63f..dcd915789ce0 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_polling.py @@ -18,10 +18,9 @@ def raise_error(response, errors, message): - message += "({}) {}\n".format(errors[0]["code"], errors[0]["message"]) - error = HttpResponseError(message=message, response=response) + error_message = "({}) {}{}".format(errors[0]["code"], errors[0]["message"], message) + error = HttpResponseError(message=error_message, response=response) error.error = ODataV4Format(errors[0]) - error.error.message = message raise error @@ -53,7 +52,7 @@ def get_status(self, pipeline_response): # pylint: disable=no-self-use if train_result: errors = train_result.get("errors") if errors: - message = "Invalid model created with ID={}\n".format(body["modelInfo"]["modelId"]) + message = "\nInvalid model created with ID={}".format(body["modelInfo"]["modelId"]) raise_error(response, errors, message) return "Failed" if status.lower() != "creating": diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py index 08073e8b3c7b..ed4bb137a591 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py @@ -62,9 +62,12 @@ def test_copy_model_fail(self, client, container_sas_url, location, resource_id) # give an incorrect region target = client.get_copy_authorization(resource_region="eastus", resource_id=resource_id) - with self.assertRaises(HttpResponseError): + try: poller = client.begin_copy_model(model.model_id, target=target) copy = poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True, copy=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py index cd0ee6cb8ff3..26aee476c65d 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py @@ -63,9 +63,12 @@ async def test_copy_model_fail(self, client, container_sas_url, location, resour # give an incorrect region target = await client.get_copy_authorization(resource_region="eastus", resource_id=resource_id) - with self.assertRaises(HttpResponseError): + try: poller = await client.begin_copy_model(model.model_id, target=target) copy = await poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True, copy=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py index d132c934c6ee..800e9aa86c4d 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py @@ -81,12 +81,15 @@ def test_custom_form_bad_url(self, client, container_sas_url): poller = client.begin_training(container_sas_url, use_training_labels=True) model = poller.result() - with self.assertRaises(HttpResponseError): + try: poller = fr_client.begin_recognize_custom_forms_from_url( model.model_id, form_url="https://badurl.jpg" ) form = poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py index 010c3a07449f..344e11ff21ae 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py @@ -62,9 +62,12 @@ async def test_url_authentication_bad_key(self, resource_group, location, form_r async def test_passing_bad_url(self, resource_group, location, form_recognizer_account, form_recognizer_account_key): client = FormRecognizerClient(form_recognizer_account, AzureKeyCredential(form_recognizer_account_key)) - with self.assertRaises(HttpResponseError): + try: poller = await client.begin_recognize_custom_forms_from_url(model_id="xx", form_url="https://badurl.jpg") result = await poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() async def test_pass_stream_into_url(self, resource_group, location, form_recognizer_account, form_recognizer_account_key): diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py index 93d255169d73..793248087e01 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py @@ -237,9 +237,12 @@ def test_training_with_files_filter(self, client, container_sas_url): self.assertEqual(len(model.training_documents), 1) self.assertEqual(model.training_documents[0].document_name, "subfolder/Form_6.jpg") # we filtered for only subfolders - with self.assertRaises(HttpResponseError): + try: poller = client.begin_training(training_files_url=container_sas_url, use_training_labels=False, prefix="xxx") model = poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py index 5ab3d350e920..e4fcf9ea8314 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py @@ -243,9 +243,12 @@ async def test_training_with_files_filter(self, client, container_sas_url): self.assertEqual(len(model.training_documents), 1) self.assertEqual(model.training_documents[0].document_name, "subfolder/Form_6.jpg") # we filtered for only subfolders - with self.assertRaises(HttpResponseError): + try: poller = await client.begin_training(training_files_url=container_sas_url, use_training_labels=False, prefix="xxx") model = await poller.result() + except HttpResponseError as e: + self.assertIsNotNone(e.error.code) + self.assertIsNotNone(e.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True) From d03f9498b88763b7b9c351299eaf0ee3eadb84e5 Mon Sep 17 00:00:00 2001 From: Krista Pratico Date: Tue, 21 Jul 2020 08:43:44 -0700 Subject: [PATCH 4/5] update changelog --- sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md b/sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md index 504b516b5b63..65ba45609545 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md +++ b/sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md @@ -6,6 +6,11 @@ - Values are now capitalized for enums `FormContentType`, `LengthUnit`, `TrainingStatus`, and `CustomFormModelStatus` +**Fixes and improvements** + +- Fixes a bug where error code and message weren't being returned on `HttpResponseError` if operation failed during polling + + ## 1.0.0b4 (2020-07-07) **Breaking Changes** From 237fa500614e7a678abded6211167156b40afa8a Mon Sep 17 00:00:00 2001 From: Krista Pratico Date: Tue, 21 Jul 2020 09:35:16 -0700 Subject: [PATCH 5/5] switch to pytest.raises for tests --- .../azure-ai-formrecognizer/tests/test_copy_model.py | 7 +++---- .../azure-ai-formrecognizer/tests/test_copy_model_async.py | 7 +++---- .../tests/test_custom_forms_from_url.py | 7 +++---- .../tests/test_custom_forms_from_url_async.py | 7 +++---- .../azure-ai-formrecognizer/tests/test_training.py | 7 +++---- .../azure-ai-formrecognizer/tests/test_training_async.py | 7 +++---- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py index ed4bb137a591..12614c9dc58a 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model.py @@ -62,12 +62,11 @@ def test_copy_model_fail(self, client, container_sas_url, location, resource_id) # give an incorrect region target = client.get_copy_authorization(resource_region="eastus", resource_id=resource_id) - try: + with pytest.raises(HttpResponseError) as e: poller = client.begin_copy_model(model.model_id, target=target) copy = poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True, copy=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py index 26aee476c65d..58e7fa1e2796 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_copy_model_async.py @@ -63,12 +63,11 @@ async def test_copy_model_fail(self, client, container_sas_url, location, resour # give an incorrect region target = await client.get_copy_authorization(resource_region="eastus", resource_id=resource_id) - try: + with pytest.raises(HttpResponseError) as e: poller = await client.begin_copy_model(model.model_id, target=target) copy = await poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True, copy=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py index 800e9aa86c4d..971acdf34bad 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url.py @@ -81,15 +81,14 @@ def test_custom_form_bad_url(self, client, container_sas_url): poller = client.begin_training(container_sas_url, use_training_labels=True) model = poller.result() - try: + with pytest.raises(HttpResponseError) as e: poller = fr_client.begin_recognize_custom_forms_from_url( model.model_id, form_url="https://badurl.jpg" ) form = poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py index 344e11ff21ae..083a05e41d12 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_custom_forms_from_url_async.py @@ -62,12 +62,11 @@ async def test_url_authentication_bad_key(self, resource_group, location, form_r async def test_passing_bad_url(self, resource_group, location, form_recognizer_account, form_recognizer_account_key): client = FormRecognizerClient(form_recognizer_account, AzureKeyCredential(form_recognizer_account_key)) - try: + with pytest.raises(HttpResponseError) as e: poller = await client.begin_recognize_custom_forms_from_url(model_id="xx", form_url="https://badurl.jpg") result = await poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() async def test_pass_stream_into_url(self, resource_group, location, form_recognizer_account, form_recognizer_account_key): diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py index 793248087e01..10b016cb0e46 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training.py @@ -237,12 +237,11 @@ def test_training_with_files_filter(self, client, container_sas_url): self.assertEqual(len(model.training_documents), 1) self.assertEqual(model.training_documents[0].document_name, "subfolder/Form_6.jpg") # we filtered for only subfolders - try: + with pytest.raises(HttpResponseError) as e: poller = client.begin_training(training_files_url=container_sas_url, use_training_labels=False, prefix="xxx") model = poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True) diff --git a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py index e4fcf9ea8314..4a0d3a51111b 100644 --- a/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py +++ b/sdk/formrecognizer/azure-ai-formrecognizer/tests/test_training_async.py @@ -243,12 +243,11 @@ async def test_training_with_files_filter(self, client, container_sas_url): self.assertEqual(len(model.training_documents), 1) self.assertEqual(model.training_documents[0].document_name, "subfolder/Form_6.jpg") # we filtered for only subfolders - try: + with pytest.raises(HttpResponseError) as e: poller = await client.begin_training(training_files_url=container_sas_url, use_training_labels=False, prefix="xxx") model = await poller.result() - except HttpResponseError as e: - self.assertIsNotNone(e.error.code) - self.assertIsNotNone(e.error.message) + self.assertIsNotNone(e.value.error.code) + self.assertIsNotNone(e.value.error.message) @GlobalFormRecognizerAccountPreparer() @GlobalClientPreparer(training=True)