diff --git a/homeassistant/components/websocket_api.py b/homeassistant/components/websocket_api.py index 609e9495f6f61..030d1bee579a0 100644 --- a/homeassistant/components/websocket_api.py +++ b/homeassistant/components/websocket_api.py @@ -5,8 +5,8 @@ https://home-assistant.io/developers/websocket_api/ """ import asyncio +from concurrent import futures from contextlib import suppress -from concurrent.futures import CancelledError from functools import partial import json import logging @@ -121,6 +121,11 @@ TYPE_PING) }, extra=vol.ALLOW_EXTRA) +# Define the possible errors that occur when connections are cancelled. +# Originally, this was just asyncio.CancelledError, but issue #9546 showed +# that futures.CancelledErrors can also occur in some situations. +CANCELLATION_ERRORS = (asyncio.CancelledError, futures.CancelledError) + def auth_ok_message(): """Return an auth_ok message.""" @@ -232,7 +237,7 @@ def log_error(self, message1, message2=''): def _writer(self): """Write outgoing messages.""" # Exceptions if Socket disconnected or cancelled by connection handler - with suppress(RuntimeError, asyncio.CancelledError, CancelledError): + with suppress(RuntimeError, *CANCELLATION_ERRORS): while not self.wsock.closed: message = yield from self.to_write.get() if message is None: @@ -364,7 +369,7 @@ def handle_hass_stop(event): self.log_error(msg) self._writer_task.cancel() - except (asyncio.CancelledError, CancelledError): + except CANCELLATION_ERRORS: self.debug("Connection cancelled by server") except asyncio.QueueFull: