diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ea830c..8941ad76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-api-core/#history +### [2.2.1](https://www.github.com/googleapis/python-api-core/compare/v2.2.0...v2.2.1) (2021-10-26) + + +### Bug Fixes + +* revert "fix: do not error on LROs with no response or error" ([#294](https://www.github.com/googleapis/python-api-core/issues/294)) ([9e6091e](https://www.github.com/googleapis/python-api-core/commit/9e6091ee59a30e72a6278b369f6a08e7aef32f22)) + ## [2.2.0](https://www.github.com/googleapis/python-api-core/compare/v2.1.1...v2.2.0) (2021-10-25) diff --git a/google/api_core/operation.py b/google/api_core/operation.py index a66e4a50..b17f753b 100644 --- a/google/api_core/operation.py +++ b/google/api_core/operation.py @@ -140,11 +140,11 @@ def _set_result_from_operation(self): ) self.set_exception(exception) else: - # Some APIs set `done: true`, with an empty response. - # Set the result to an empty message of the expected - # result type. - # https://google.aip.dev/151 - self.set_result(self._result_type()) + exception = exceptions.GoogleAPICallError( + "Unexpected state: Long-running operation had neither " + "response nor error set." + ) + self.set_exception(exception) def _refresh_and_update(self, retry=polling.DEFAULT_RETRY): """Refresh the operation and update the result if needed. diff --git a/google/api_core/operation_async.py b/google/api_core/operation_async.py index 17624d62..6bae8654 100644 --- a/google/api_core/operation_async.py +++ b/google/api_core/operation_async.py @@ -136,11 +136,11 @@ def _set_result_from_operation(self): ) self.set_exception(exception) else: - # Some APIs set `done: true`, with an empty response. - # Set the result to an empty message of the expected - # result type. - # https://google.aip.dev/151 - self.set_result(self._result_type()) + exception = exceptions.GoogleAPICallError( + "Unexpected state: Long-running operation had neither " + "response nor error set." + ) + self.set_exception(exception) async def _refresh_and_update(self, retry=async_future.DEFAULT_RETRY): """Refresh the operation and update the result if needed. diff --git a/google/api_core/version.py b/google/api_core/version.py index bd0f8e5c..b1be7d8c 100644 --- a/google/api_core/version.py +++ b/google/api_core/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.2.0" +__version__ = "2.2.1" diff --git a/tests/asyncio/test_operation_async.py b/tests/asyncio/test_operation_async.py index 886b1c8d..26ad7cef 100644 --- a/tests/asyncio/test_operation_async.py +++ b/tests/asyncio/test_operation_async.py @@ -158,7 +158,7 @@ async def test_exception(): @mock.patch("asyncio.sleep", autospec=True) @pytest.mark.asyncio -async def test_done_with_no_error_or_response(unused_sleep): +async def test_unexpected_result(unused_sleep): responses = [ make_operation_proto(), # Second operation response is done, but has not error or response. @@ -166,9 +166,9 @@ async def test_done_with_no_error_or_response(unused_sleep): ] future, _, _ = make_operation_future(responses) - result = await future.result() + exception = await future.exception() - assert isinstance(result, struct_pb2.Struct) + assert "Unexpected state" in "{!r}".format(exception) def test_from_gapic(): diff --git a/tests/unit/test_operation.py b/tests/unit/test_operation.py index bafff8b0..22e23bc3 100644 --- a/tests/unit/test_operation.py +++ b/tests/unit/test_operation.py @@ -169,7 +169,7 @@ def test_exception_with_error_code(): assert isinstance(exception, exceptions.NotFound) -def test_done_with_no_error_or_response(): +def test_unexpected_result(): responses = [ make_operation_proto(), # Second operation response is done, but has not error or response. @@ -177,7 +177,9 @@ def test_done_with_no_error_or_response(): ] future, _, _ = make_operation_future(responses) - assert isinstance(future.result(), struct_pb2.Struct) + exception = future.exception() + + assert "Unexpected state" in "{!r}".format(exception) def test__refresh_http():