Fehlerhandling ausgearbeitet
This commit is contained in:
parent
0330c9fa1e
commit
7877faa786
2 changed files with 55 additions and 13 deletions
22
app/cli.py
22
app/cli.py
|
|
@ -163,11 +163,25 @@ def main() -> None:
|
||||||
sys.exit(demo_workspace.run(settings, args.names, args.reset))
|
sys.exit(demo_workspace.run(settings, args.names, args.reset))
|
||||||
elif args.command == "web":
|
elif args.command == "web":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
# Logging wie oben eingerichtet; die Zugriffszeile schreibt die App selbst (mit Request-ID)
|
# Start und Abbruch immer auf stderr, unabhängig von AIW_LOG_LEVEL: sonst endet ein Fehlstart still
|
||||||
uvicorn.run("app.main:create_app", factory=True, host=args.host, port=args.port, reload=args.reload,
|
print(f"aiw web: starte auf http://{args.host}:{args.port} (Log-Level {settings.log_level})", file=sys.stderr)
|
||||||
log_config=None, access_log=False)
|
try:
|
||||||
|
# Logging wie oben eingerichtet; die Zugriffszeile schreibt die App selbst (mit Request-ID)
|
||||||
|
uvicorn.run("app.main:create_app", factory=True, host=args.host, port=args.port, reload=args.reload,
|
||||||
|
log_config=None, access_log=False)
|
||||||
|
except SystemExit as exit:
|
||||||
|
if exit.code:
|
||||||
|
print(f"aiw web: Start fehlgeschlagen (Exit-Code {exit.code}), z. B. Port {args.port} belegt oder "
|
||||||
|
"Fehler beim Laden der App. Details mit AIW_LOG_LEVEL=DEBUG.", file=sys.stderr)
|
||||||
|
raise
|
||||||
elif args.command == "worker":
|
elif args.command == "worker":
|
||||||
run_worker(settings)
|
port = settings.worker_http_port or "aus"
|
||||||
|
print(f"aiw worker: starte (Health-Port {port}, Log-Level {settings.log_level})", file=sys.stderr)
|
||||||
|
try:
|
||||||
|
run_worker(settings)
|
||||||
|
except Exception as error:
|
||||||
|
print(f"aiw worker: abgebrochen: {type(error).__name__}: {error}", file=sys.stderr)
|
||||||
|
raise
|
||||||
elif args.command == "create-admin":
|
elif args.command == "create-admin":
|
||||||
create_admin_user(settings, args.username)
|
create_admin_user(settings, args.username)
|
||||||
elif args.command in ("backup", "restore", "check"):
|
elif args.command in ("backup", "restore", "check"):
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,20 @@ fail() { printf '\033[31m%s\033[0m\n' "$*" >&2; exit 1; }
|
||||||
# Zeilen eines Prozesses mit Namen versehen (portabel, auch mit der Bash von macOS)
|
# Zeilen eines Prozesses mit Namen versehen (portabel, auch mit der Bash von macOS)
|
||||||
prefix() { while IFS= read -r line; do printf '[%-6s] %s\n' "$1" "$line"; done; }
|
prefix() { while IFS= read -r line; do printf '[%-6s] %s\n' "$1" "$line"; done; }
|
||||||
|
|
||||||
port_busy() { lsof -nP -iTCP:"$1" -sTCP:LISTEN >/dev/null 2>&1; }
|
# Lauscht etwas auf dem Port? Mit lsof, sonst (z. B. Linux ohne lsof) per Verbindungsversuch
|
||||||
|
port_busy() {
|
||||||
|
if command -v lsof >/dev/null 2>&1; then
|
||||||
|
lsof -nP -iTCP:"$1" -sTCP:LISTEN >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
(exec 3<>"/dev/tcp/127.0.0.1/$1") 2>/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wer belegt den Port? (für die Fehlermeldung; leer, wenn es sich nicht feststellen lässt)
|
||||||
|
port_owner() {
|
||||||
|
command -v lsof >/dev/null 2>&1 || return 0
|
||||||
|
lsof -nP -iTCP:"$1" -sTCP:LISTEN 2>/dev/null | awk 'NR == 2 { print $1 " (PID " $2 ")" }'
|
||||||
|
}
|
||||||
|
|
||||||
env_value() { grep -E "^$1=" .env 2>/dev/null | tail -1 | cut -d= -f2-; }
|
env_value() { grep -E "^$1=" .env 2>/dev/null | tail -1 | cut -d= -f2-; }
|
||||||
|
|
||||||
|
|
@ -108,7 +121,11 @@ fi
|
||||||
|
|
||||||
[ -f .env ] || fail "Keine .env. Ersteinrichtung mit: scripts/dev.sh --setup"
|
[ -f .env ] || fail "Keine .env. Ersteinrichtung mit: scripts/dev.sh --setup"
|
||||||
[ -n "${AIW_SECRET_KEY:-$(env_value AIW_SECRET_KEY)}" ] || fail "AIW_SECRET_KEY fehlt in .env (scripts/dev.sh --setup)."
|
[ -n "${AIW_SECRET_KEY:-$(env_value AIW_SECRET_KEY)}" ] || fail "AIW_SECRET_KEY fehlt in .env (scripts/dev.sh --setup)."
|
||||||
port_busy "$PORT" && fail "Port $PORT ist belegt (läuft Bifröst schon?). Anderer Port: --port 8000"
|
port_busy "$PORT" && fail "Port $PORT ist belegt $(port_owner "$PORT") (läuft Bifröst schon?). Anderer Port: --port 8000"
|
||||||
|
WORKER_PORT=${AIW_WORKER_HTTP_PORT:-$(env_value AIW_WORKER_HTTP_PORT)}
|
||||||
|
WORKER_PORT=${WORKER_PORT:-9101}
|
||||||
|
port_busy "$WORKER_PORT" && fail "Port $WORKER_PORT (Health des Workers) ist belegt $(port_owner "$WORKER_PORT") \
|
||||||
|
– läuft noch ein Worker? Stoppen oder AIW_WORKER_HTTP_PORT in .env ändern."
|
||||||
|
|
||||||
say "PostgreSQL starten (127.0.0.1:55433)"
|
say "PostgreSQL starten (127.0.0.1:55433)"
|
||||||
docker compose up -d --wait postgres
|
docker compose up -d --wait postgres
|
||||||
|
|
@ -126,7 +143,11 @@ export AIW_COOKIE_SECURE=${AIW_COOKIE_SECURE:-false}
|
||||||
export PYTHONUNBUFFERED=1
|
export PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
trap 'trap - INT TERM EXIT; echo; say "Stoppe Web, Worker und DB-Dienste"; kill 0 2>/dev/null; wait 2>/dev/null' INT TERM EXIT
|
trap 'trap - INT TERM EXIT; echo; say "Stoppe Web, Worker und DB-Dienste"; kill 0 2>/dev/null; wait 2>/dev/null' INT TERM EXIT
|
||||||
|
# Gestartete Prozesse: PID, Name und Befehl zum Einzelstart (parallele Listen, Bash 3 von macOS kennt keine Maps)
|
||||||
PIDS=()
|
PIDS=()
|
||||||
|
NAMES=()
|
||||||
|
COMMANDS=()
|
||||||
|
started() { PIDS+=("$1"); NAMES+=("$2"); COMMANDS+=("$3"); }
|
||||||
|
|
||||||
HINTS=()
|
HINTS=()
|
||||||
|
|
||||||
|
|
@ -140,7 +161,8 @@ db_service() {
|
||||||
say "DB-Dienst $engine starten (Port $port)"
|
say "DB-Dienst $engine starten (Port $port)"
|
||||||
(cd services/db-mcp && DBMCP_API_KEYS="dev:$DEV_KEY" DBMCP_ALLOW_LOCAL=true DBMCP_PORT=$port \
|
(cd services/db-mcp && DBMCP_API_KEYS="dev:$DEV_KEY" DBMCP_ALLOW_LOCAL=true DBMCP_PORT=$port \
|
||||||
DBMCP_BIND=127.0.0.1 "$ROOT/.venv/bin/python" -m "dbmcp.$engine" 2>&1 | prefix "$engine") &
|
DBMCP_BIND=127.0.0.1 "$ROOT/.venv/bin/python" -m "dbmcp.$engine" 2>&1 | prefix "$engine") &
|
||||||
PIDS+=($!)
|
started $! "DB-Dienst $engine (Port $port)" \
|
||||||
|
"cd services/db-mcp && DBMCP_API_KEYS=dev:$DEV_KEY DBMCP_ALLOW_LOCAL=true DBMCP_PORT=$port ../../.venv/bin/python -m dbmcp.$engine"
|
||||||
for _ in $(seq 50); do curl -sf "http://127.0.0.1:$port/ready" >/dev/null 2>&1 && break; sleep 0.2; done
|
for _ in $(seq 50); do curl -sf "http://127.0.0.1:$port/ready" >/dev/null 2>&1 && break; sleep 0.2; done
|
||||||
fi
|
fi
|
||||||
HINTS+=("$engine: URL http://localhost:$port/mcp Schlüssel des Dienstes $DEV_KEY")
|
HINTS+=("$engine: URL http://localhost:$port/mcp Schlüssel des Dienstes $DEV_KEY")
|
||||||
|
|
@ -160,10 +182,10 @@ fi
|
||||||
|
|
||||||
say "Web starten: http://127.0.0.1:$PORT"
|
say "Web starten: http://127.0.0.1:$PORT"
|
||||||
(uv run aiw web --port "$PORT" 2>&1 | prefix web) &
|
(uv run aiw web --port "$PORT" 2>&1 | prefix web) &
|
||||||
PIDS+=($!)
|
started $! "Web (Port $PORT)" "uv run aiw web --port $PORT"
|
||||||
say "Worker starten"
|
say "Worker starten"
|
||||||
(uv run aiw worker 2>&1 | prefix worker) &
|
(uv run aiw worker 2>&1 | prefix worker) &
|
||||||
PIDS+=($!)
|
started $! "Worker" "uv run aiw worker"
|
||||||
|
|
||||||
if $RESET; then
|
if $RESET; then
|
||||||
say "Fertig von null. Noch offen: als admin ein Modell einrichten (Administration → Modelle und Zugänge)."
|
say "Fertig von null. Noch offen: als admin ein Modell einrichten (Administration → Modelle und Zugänge)."
|
||||||
|
|
@ -174,11 +196,17 @@ else
|
||||||
fi
|
fi
|
||||||
for hint in "${HINTS[@]}"; do echo " $hint"; done
|
for hint in "${HINTS[@]}"; do echo " $hint"; done
|
||||||
|
|
||||||
# Endet ein Prozess (z. B. Fehler beim Start), alles stoppen
|
# Endet ein Prozess (z. B. Fehler beim Start), sagen welcher und alles stoppen
|
||||||
while true; do
|
while true; do
|
||||||
for pid in "${PIDS[@]}"; do
|
for i in "${!PIDS[@]}"; do
|
||||||
if ! kill -0 "$pid" 2>/dev/null; then
|
if ! kill -0 "${PIDS[$i]}" 2>/dev/null; then
|
||||||
fail "Ein Prozess hat sich beendet (siehe Log oben)."
|
code=0
|
||||||
|
wait "${PIDS[$i]}" 2>/dev/null || code=$?
|
||||||
|
echo
|
||||||
|
printf '\033[31m%s hat sich beendet (Exit-Code %s).\033[0m\n' "${NAMES[$i]}" "$code" >&2
|
||||||
|
echo "Seine Ausgabe steht oben mit Präfix; fehlt sie, den Prozess einzeln starten und die Meldung ansehen:" >&2
|
||||||
|
echo " ${COMMANDS[$i]}" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue