Skip to content

Commit 85b2647

Browse files
authored
Shut down core event loop on unrecoverable errors (home-assistant#144806)
1 parent bddbf9c commit 85b2647

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

homeassistant/runner.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from contextlib import contextmanager
88
import dataclasses
99
from datetime import datetime
10+
import errno
1011
import fcntl
1112
from io import TextIOWrapper
1213
import json
@@ -207,11 +208,20 @@ def new_event_loop(self) -> asyncio.AbstractEventLoop:
207208

208209

209210
@callback
210-
def _async_loop_exception_handler(_: Any, context: dict[str, Any]) -> None:
211+
def _async_loop_exception_handler(
212+
loop: asyncio.AbstractEventLoop,
213+
context: dict[str, Any],
214+
) -> None:
211215
"""Handle all exception inside the core loop."""
216+
fatal_error: str | None = None
212217
kwargs = {}
213218
if exception := context.get("exception"):
214219
kwargs["exc_info"] = (type(exception), exception, exception.__traceback__)
220+
if isinstance(exception, OSError) and exception.errno == errno.EMFILE:
221+
# Too many open files – something is leaking them, and it's likely
222+
# to be quite unrecoverable if the event loop can't pump messages
223+
# (e.g. unable to accept a socket).
224+
fatal_error = str(exception)
215225

216226
logger = logging.getLogger(__package__)
217227
if source_traceback := context.get("source_traceback"):
@@ -232,6 +242,14 @@ def _async_loop_exception_handler(_: Any, context: dict[str, Any]) -> None:
232242
**kwargs, # type: ignore[arg-type]
233243
)
234244

245+
if fatal_error:
246+
logger.error(
247+
"Fatal error '%s' raised in event loop, shutting it down",
248+
fatal_error,
249+
)
250+
loop.stop()
251+
loop.close()
252+
235253

236254
async def setup_and_run_hass(runtime_config: RuntimeConfig) -> int:
237255
"""Set up Home Assistant and run."""

0 commit comments

Comments
 (0)