1158
1158
if response.body is not None:
1159
1159
self._write_prefixed_body(response.body)
1160
1160
elif response.body_stream is not None:
1161
for chunk in response.body_stream:
1162
self._write_prefixed_body(chunk)
1161
for exc_info, chunk in _iter_with_errors(response.body_stream):
1162
if exc_info is not None:
1163
self._write_error_status()
1164
error_struct = request._translate_error(exc_info[1])
1165
self._write_structure(error_struct)
1168
self._write_prefixed_body(chunk)
1164
1170
self._write_end()
1173
def _iter_with_errors(iterable):
1174
"""Handle errors from iterable.next().
1178
for exc_info, value in _iter_with_errors(iterable):
1181
This is a safer alternative to::
1184
for value in iterable:
1189
Because the latter will catch errors from the for-loop body, not just
1192
If an error occurs, exc_info will be a exc_info tuple, and the generator
1193
will terminate. Otherwise exc_info will be None, and value will be the
1194
value from iterable.next(). Note that KeyboardInterrupt and SystemExit
1195
will not be itercepted.
1197
iterator = iter(iterable)
1200
yield None, iterator.next()
1201
except StopIteration:
1203
except (KeyboardInterrupt, SystemExit):
1206
yield sys.exc_info(), None
1167
1210
class ProtocolThreeRequester(_ProtocolThreeEncoder, Requester):
1169
1212
def __init__(self, medium_request):
1242
1285
# have finished sending the stream. We would notice at the end
1243
1286
# anyway, but if the medium can deliver it early then it's good
1244
1287
# to short-circuit the whole request...
1288
for exc_info, part in _iter_with_errors(stream):
1289
if exc_info is not None:
1290
# Iterating the stream failed. Cleanly abort the request.
1291
self._write_error_status()
1292
# Currently the client unconditionally sends ('error',) as the
1294
self._write_structure(('error',))
1296
self._medium_request.finished_writing()
1297
raise exc_info[0], exc_info[1], exc_info[2]
1247
1299
self._write_prefixed_body(part)
1250
exc_info = sys.exc_info()
1251
# Iterating the stream failed. Cleanly abort the request.
1252
self._write_error_status()
1253
# Currently the client unconditionally sends ('error',) as the
1255
self._write_structure(('error',))
1257
self._medium_request.finished_writing()
1258
raise exc_info[0], exc_info[1], exc_info[2]
1259
1301
self._write_end()
1260
1302
self._medium_request.finished_writing()