Skip to content

Commit 9e6091e

Browse files
authored
fix: revert "fix: do not error on LROs with no response or error" (#294)
Reverts #258 From @TrucHLe > A while ago you helped me submit this pull request for the Python LRO client library. This was about making the LRO library not throw an error when receiving an empty LRO response. It turns out that the Python LRO library has always been behaving correctly by accepting empty LRO responses. It would just throw an error if the response field is NULL (see screenshot). > > Since then I've consulted other LRO client library owners (@vam-google ) and it turns out that the fault was in the CCAI Insights server code. CCAI Insights was returning NULL responses instead of empty responses (more context here b/202432905). Since then the issue has been fixed in our server and has rolled out to production, so reverting the Python LRO false fix wouldn't break our code sample.
1 parent 240edb6 commit 9e6091e

File tree

4 files changed

+17
-15
lines changed

4 files changed

+17
-15
lines changed

google/api_core/operation.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ def _set_result_from_operation(self):
140140
)
141141
self.set_exception(exception)
142142
else:
143-
# Some APIs set `done: true`, with an empty response.
144-
# Set the result to an empty message of the expected
145-
# result type.
146-
# https://google.aip.dev/151
147-
self.set_result(self._result_type())
143+
exception = exceptions.GoogleAPICallError(
144+
"Unexpected state: Long-running operation had neither "
145+
"response nor error set."
146+
)
147+
self.set_exception(exception)
148148

149149
def _refresh_and_update(self, retry=polling.DEFAULT_RETRY):
150150
"""Refresh the operation and update the result if needed.

google/api_core/operation_async.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ def _set_result_from_operation(self):
136136
)
137137
self.set_exception(exception)
138138
else:
139-
# Some APIs set `done: true`, with an empty response.
140-
# Set the result to an empty message of the expected
141-
# result type.
142-
# https://google.aip.dev/151
143-
self.set_result(self._result_type())
139+
exception = exceptions.GoogleAPICallError(
140+
"Unexpected state: Long-running operation had neither "
141+
"response nor error set."
142+
)
143+
self.set_exception(exception)
144144

145145
async def _refresh_and_update(self, retry=async_future.DEFAULT_RETRY):
146146
"""Refresh the operation and update the result if needed.

tests/asyncio/test_operation_async.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,17 @@ async def test_exception():
158158

159159
@mock.patch("asyncio.sleep", autospec=True)
160160
@pytest.mark.asyncio
161-
async def test_done_with_no_error_or_response(unused_sleep):
161+
async def test_unexpected_result(unused_sleep):
162162
responses = [
163163
make_operation_proto(),
164164
# Second operation response is done, but has not error or response.
165165
make_operation_proto(done=True),
166166
]
167167
future, _, _ = make_operation_future(responses)
168168

169-
result = await future.result()
169+
exception = await future.exception()
170170

171-
assert isinstance(result, struct_pb2.Struct)
171+
assert "Unexpected state" in "{!r}".format(exception)
172172

173173

174174
def test_from_gapic():

tests/unit/test_operation.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,17 @@ def test_exception_with_error_code():
169169
assert isinstance(exception, exceptions.NotFound)
170170

171171

172-
def test_done_with_no_error_or_response():
172+
def test_unexpected_result():
173173
responses = [
174174
make_operation_proto(),
175175
# Second operation response is done, but has not error or response.
176176
make_operation_proto(done=True),
177177
]
178178
future, _, _ = make_operation_future(responses)
179179

180-
assert isinstance(future.result(), struct_pb2.Struct)
180+
exception = future.exception()
181+
182+
assert "Unexpected state" in "{!r}".format(exception)
181183

182184

183185
def test__refresh_http():

0 commit comments

Comments
 (0)