ZhuLinsen/daily_stock_analysis · critical · RuntimeError
FastAPI 服务器启动后立即退出: {host}:{port}
Error message
FastAPI 服务器启动后立即退出: {host}:{port} What it means
After the wait loop, the uvicorn server thread is dead, no exception was captured, and uvicorn_server.started is False — the process exited silently right after launch. Usually uvicorn received a shutdown signal, install-level signal handlers interfered, or run_server returned without raising (swallowed exception path).
Source
Thrown at main.py:1272
while time.time() < wait_deadline:
if startup_error:
raise RuntimeError(
f"FastAPI server failed to start: {host}:{port}; {startup_error[0]}"
)
if uvicorn_server.started:
logger.info(f"FastAPI 服务已启动: http://{host}:{port}")
return
if not thread.is_alive():
break
time.sleep(0.05)
if startup_error:
raise RuntimeError(f"FastAPI server failed to start: {host}:{port}; {startup_error[0]}")
if uvicorn_server.started:
logger.info(f"FastAPI 服务已启动: http://{host}:{port}")
return
if not thread.is_alive():
raise RuntimeError(f"FastAPI 服务器启动后立即退出: {host}:{port}")
raise RuntimeError(f"FastAPI 服务在 {timeout_seconds:.1f}s 内未完成启动: {host}:{port}")
def _is_truthy_env(var_name: str, default: str = "true") -> bool:
"""Parse common truthy / falsy environment values."""
value = os.getenv(var_name, default).strip().lower()
return value not in {"0", "false", "no", "off"}
def start_bot_stream_clients(config: Config) -> None:
"""Start bot stream clients when enabled in config."""
# 启动钉钉 Stream 客户端
if config.dingtalk_stream_enabled:
try:
from bot.platforms import start_dingtalk_stream_background, DINGTALK_STREAM_AVAILABLE
if DINGTALK_STREAM_AVAILABLE:
if start_dingtalk_stream_background():View on GitHub (pinned to 5159bd72e8)
Solutions
- Check whether anything sends signals to the process at startup (supervisor, docker stop, CI timeout) and delay or disable that.
- Verify the imported ASGI app is a real object: python -c "import server; print(server.app)".
- Broaden the except in run_server to BaseException (or add logging on thread exit via threading.excepthook) so silent deaths become diagnosable.
- Retry once after clearing the environment (stray SIGINT from a terminal job-control issue).
Example fix
# before
def run_server():
try:
uvicorn_server.run()
except Exception as exc: # SystemExit/KeyboardInterrupt vanish silently
startup_error.append(exc)
# after
def run_server():
try:
uvicorn_server.run()
except BaseException as exc: # capture silent thread deaths
startup_error.append(exc) Defensive patterns
Strategy: try-catch
Validate before calling
import threading
threading.excepthook = lambda args: logger.error("thread %s died: %s", args.thread.name, args.exc_value) # install before server start Try / catch
try:
run_fastapi(host, port, config)
except RuntimeError as e:
if "立即退出" in str(e):
logger.error("server thread died silently; check signals and app import")
subprocess.run([sys.executable, "-c", "import server"], check=True) # preflight
raise Prevention
- Ensure supervisors/CI do not deliver SIGTERM during the startup window.
- Verify the ASGI app object is non-None before handing it to uvicorn.
- Capture BaseException in the server thread so silent exits become reported errors.
When it happens
Trigger: SIGTERM/SIGINT reaching the daemon thread during startup; use_config_signal_handlers interacting badly with the environment; run_server exiting normally because uvicorn_server.run() returned immediately (e.g. empty/None app passed after an import returned None); an exception type not derived from Exception (SystemExit, KeyboardInterrupt) bypassing the except clause and killing the thread silently.
Common situations: Running under a supervisor or test harness that delivers signals at startup; the app object import returning None; KeyboardInterrupt during the 3s startup window.
Related errors
- FastAPI server failed to start: {host}:{port}; {startup_erro
- FastAPI port is not available: {host}:{port}
- FastAPI 服务在 {timeout_seconds:.1f}s 内未完成启动: {host}:{port}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/1a07a85ec218698c.
Report an issue: GitHub.