Skip to content

Commit 48dbb71

Browse files
authored
fix: add a helpful hint for when EADDRINUSE happens during startup (#1526)
1 parent f5e55ff commit 48dbb71

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/zeroconf/_utils/net.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,25 @@ def new_socket(
262262
bind_tup,
263263
)
264264
return None
265+
if ex.errno == errno.EADDRINUSE:
266+
if sys.platform.startswith("darwin") or sys.platform.startswith("freebsd"):
267+
log.error(
268+
"Address in use when binding to %s; "
269+
"On BSD based systems sharing the same port with another "
270+
"stack may require processes to run with the same UID; "
271+
"When using avahi, make sure disallow-other-stacks is set"
272+
" to no in avahi-daemon.conf",
273+
bind_tup,
274+
)
275+
else:
276+
log.error(
277+
"Address in use when binding to %s; "
278+
"When using avahi, make sure disallow-other-stacks is set"
279+
" to no in avahi-daemon.conf",
280+
bind_tup,
281+
)
282+
# This is still a fatal error as its not going to work
283+
# if we can't hear the traffic coming in.
265284
raise
266285
log.debug("Created socket %s", s)
267286
return s

tests/utils/test_net.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,40 @@ def _mock_socket(*args, **kwargs):
260260
netutils.new_socket(("0.0.0.0", 0)) # type: ignore[arg-type]
261261

262262

263+
def test_bind_raises_address_in_use(caplog: pytest.LogCaptureFixture) -> None:
264+
"""Test bind failing in new_socket returns None on EADDRINUSE."""
265+
266+
def _mock_socket(*args, **kwargs):
267+
sock = MagicMock()
268+
sock.bind = MagicMock(side_effect=OSError(errno.EADDRINUSE, f"Error: {errno.EADDRINUSE}"))
269+
return sock
270+
271+
with (
272+
pytest.raises(OSError),
273+
patch.object(sys, "platform", "darwin"),
274+
patch("socket.socket", _mock_socket),
275+
):
276+
netutils.new_socket(("0.0.0.0", 0)) # type: ignore[arg-type]
277+
assert (
278+
"On BSD based systems sharing the same port with "
279+
"another stack may require processes to run with the same UID"
280+
) in caplog.text
281+
assert (
282+
"When using avahi, make sure disallow-other-stacks is set to no in avahi-daemon.conf" in caplog.text
283+
)
284+
285+
caplog.clear()
286+
with pytest.raises(OSError), patch.object(sys, "platform", "linux"), patch("socket.socket", _mock_socket):
287+
netutils.new_socket(("0.0.0.0", 0)) # type: ignore[arg-type]
288+
assert (
289+
"On BSD based systems sharing the same port with "
290+
"another stack may require processes to run with the same UID"
291+
) not in caplog.text
292+
assert (
293+
"When using avahi, make sure disallow-other-stacks is set to no in avahi-daemon.conf" in caplog.text
294+
)
295+
296+
263297
def test_new_respond_socket_new_socket_returns_none():
264298
"""Test new_respond_socket returns None if new_socket returns None."""
265299
with patch.object(netutils, "new_socket", return_value=None):

0 commit comments

Comments
 (0)