Skip to content

uvloop: after CancelledError web response still tries to write EOF to closed socket #1790

Closed
@balloob

Description

Long story short

If a CancelledError is raised while a web response handler is waiting for it's data, aiohttp fails when trying to write EOF to the closed socket.

This issue only happens when using UVLoop. If I use UnixSelectorEventLoop (default on OS X) I do not experience this issue. That's why I am not 100% sure if this issue is related to aiohttp or UVLoop. I will work on getting an isolated test case together tomorrow.

Expected behaviour

Premature client cancelling should be handled correctly.

Actual behaviour

17-04-05 23:54:51 ERROR (MainThread) [aiohttp.server] Unhandled exception
Traceback (most recent call last):
  File "/Users/paulus/dev/python/home-assistant/homeassistant/components/camera/__init__.py", line 269, in handle
    image = yield from camera.async_camera_image()
  File "/Users/paulus/dev/python/home-assistant/homeassistant/components/camera/mjpeg.py", line 92, in async_camera_image
    None, self.camera_image)
  File "uvloop/future.pyx", line 230, in __iter__ (uvloop/loop.c:110600)
  File "uvloop/future.pyx", line 432, in uvloop.loop.BaseTask._fast_wakeup (uvloop/loop.c:113980)
  File "uvloop/future.pyx", line 96, in uvloop.loop.BaseFuture._result_impl (uvloop/loop.c:108829)
concurrent.futures._base.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/paulus/dev/python/home-assistant/config/deps/aiohttp/web_protocol.py", line 430, in start
    yield from resp.write_eof()
  File "/Users/paulus/dev/python/home-assistant/config/deps/aiohttp/web_response.py", line 576, in write_eof
    yield from super().write_eof()
  File "/Users/paulus/dev/python/home-assistant/config/deps/aiohttp/web_response.py", line 413, in write_eof
    yield from self._payload_writer.write_eof(data)
  File "/Users/paulus/dev/python/home-assistant/config/deps/aiohttp/http_writer.py", line 281, in write_eof
    yield from self.drain(True)
  File "/Users/paulus/dev/python/home-assistant/config/deps/aiohttp/http_writer.py", line 291, in drain
    self._transport.write(b''.join(self._buffer))
  File "uvloop/handles/stream.pyx", line 632, in uvloop.loop.UVStream.write (uvloop/loop.c:74612)
  File "uvloop/handles/handle.pyx", line 150, in uvloop.loop.UVHandle._ensure_alive (uvloop/loop.c:54917)
RuntimeError: unable to perform operation on <TCPTransport closed=True reading=False 0x7fa24400b858>; the handler is closed

Right after this exception, aiohttp writes to the debug log (in both loops): Ignored premature client disconnection.

Steps to reproduce

Going to sleep first, will get to this tomorrow 👍

Your environment

OS X, aiohttp 2.0.5

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions