Skip to content

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

@balloob

Description

@balloob

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

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions