diff --git a/bot.py b/bot.py index c6cbf1f..76dacbe 100755 --- a/bot.py +++ b/bot.py @@ -120,13 +120,15 @@ SERVICE_EXTENSION_GROUPS = { SERVICE_RECHECK_SECONDS = 300 -def _service_alive(url: str) -> bool: - """True when the service answers HTTP at all (any status code counts).""" +def _service_health(url: str): + """Return None when the service answers HTTP at all (any status counts), + otherwise the connection error explaining WHY it's unreachable (refused vs + timeout vs DNS - the difference points straight at the cause).""" try: requests.get(url, timeout=3) - return True - except requests.exceptions.RequestException: - return False + return None + except requests.exceptions.RequestException as exc: + return exc async def _load_extension_safe(name: str) -> bool: @@ -152,12 +154,14 @@ async def _load_service_groups() -> bool: missing = [e for e in group["extensions"] if e not in client.extensions] if not missing: continue - alive = await asyncio.to_thread(_service_alive, group["health_url"]) - if not alive: + err = await asyncio.to_thread(_service_health, group["health_url"]) + if err is not None: logger.warning( - "Service '%s' unreachable (%s) - cogs stay disabled: %s", + "Service '%s' unreachable (%s) [%s: %s] - cogs stay disabled: %s", service, group["health_url"], + type(err).__name__, + err, ", ".join(missing), ) continue @@ -204,6 +208,16 @@ async def on_ready(): for extension in CORE_EXTENSIONS: await _load_extension_safe(extension) + # Log the ACTUALLY-resolved service addresses. When one shows the built-in + # default (192.168.1.15:5000) it means the matching CONJURER_* env var never + # reached the process - the single most common cause of "service unreachable" + # confusion. Printing them makes env-vs-default obvious at a glance. + logger.info( + "Resolved service addresses -> musician(file): %s | librarian: %s | radio: %s", + FILE_SERVICE_ADDRESS, + LIBRARIAN_SERVICE_ADDRESS, + RADIO_SERVICE_ADDRESS, + ) await _load_service_groups() logger.info("Sensors: online")