Skip to content

Commit c4f8562

Browse files
author
Fabian Reinartz
committed
Handle error events in watch
Raise an ApiException for error events that indicate a watch failure despite the HTTP response indicating success. Fixes kubernetes-client#57 Signed-off-by: Fabian Reinartz <[email protected]>
1 parent 879ab01 commit c4f8562

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

watch/watch.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,14 @@ def stream(self, func, *args, **kwargs):
128128
resp = func(*args, **kwargs)
129129
try:
130130
for line in iter_resp_lines(resp):
131-
yield self.unmarshal_event(line, return_type)
131+
evt = self.unmarshal_event(line, return_type)
132+
if evt['type'] == 'ERROR':
133+
obj = evt['raw_object']
134+
reason = "%s: %s" % (obj['reason'], obj['message'])
135+
raise client.rest.ApiException(status=obj['code'],
136+
reason=reason)
137+
yield evt
138+
132139
if self._stop:
133140
break
134141
finally:

watch/watch_test.py

+27
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import unittest
1616

1717
from mock import Mock
18+
from kubernetes import client
1819

1920
from .watch import Watch
2021

@@ -173,6 +174,32 @@ def test_watch_with_exception(self):
173174
fake_resp.close.assert_called_once()
174175
fake_resp.release_conn.assert_called_once()
175176

177+
def test_watch_with_error_event(self):
178+
print("start")
179+
fake_resp = Mock()
180+
fake_resp.close = Mock()
181+
fake_resp.release_conn = Mock()
182+
fake_resp.read_chunked = Mock(
183+
return_value=[
184+
'{"type": "ERROR", "object": {"code": 410, '
185+
'"reason": "Gone", "message": "error message"}}\n'])
186+
187+
fake_api = Mock()
188+
fake_api.get_thing = Mock(return_value=fake_resp)
189+
190+
w = Watch()
191+
try:
192+
for _ in w.stream(fake_api.get_thing):
193+
self.fail(self, "Should fail with ApiException.")
194+
except client.rest.ApiException:
195+
pass
196+
197+
fake_api.get_thing.assert_called_once_with(
198+
_preload_content=False, watch=True)
199+
fake_resp.read_chunked.assert_called_once_with(decode_content=False)
200+
fake_resp.close.assert_called_once()
201+
fake_resp.release_conn.assert_called_once()
202+
176203

177204
if __name__ == '__main__':
178205
unittest.main()

0 commit comments

Comments
 (0)