Spaces:
Running
Running
Add proxy error cause logging, clean up startup logs
Browse files- cloudflare-proxy.js: add logProxyError() to log actual fetch failure
cause (error.cause.code/message) so Gemini errors are visible in logs;
fix DEBUG hardcode (|| true); only add duplex:half for ReadableStream
bodies; normalize proxiedUrl to string in all fetch paths
- start.sh: replace boxed config table with simple key:value lines
matching Hugging8n style; drop emoji noise from log lines; remove HF
token validation curl (was noisy and not critical path)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- cloudflare-proxy.js +21 -4
- start.sh +19 -64
cloudflare-proxy.js
CHANGED
|
@@ -21,7 +21,7 @@ if (
|
|
| 21 |
PROXY_URL = `https://${PROXY_URL}`;
|
| 22 |
}
|
| 23 |
|
| 24 |
-
const DEBUG = process.env.CLOUDFLARE_PROXY_DEBUG === "true"
|
| 25 |
const PROXY_SHARED_SECRET = (process.env.CLOUDFLARE_PROXY_SECRET || "").trim();
|
| 26 |
const PROXY_DOMAINS = process.env.CLOUDFLARE_PROXY_DOMAINS || "*";
|
| 27 |
const BLOCKED_DOMAINS = PROXY_DOMAINS.split(",")
|
|
@@ -176,6 +176,23 @@ if (PROXY_URL) {
|
|
| 176 |
|
| 177 |
const proxiedUrl = new URL(url.pathname + url.search, proxy);
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
if (request) {
|
| 180 |
const fetchOpts = {
|
| 181 |
method: request.method,
|
|
@@ -186,18 +203,18 @@ if (PROXY_URL) {
|
|
| 186 |
fetchOpts.body = request.body;
|
| 187 |
fetchOpts.duplex = "half";
|
| 188 |
}
|
| 189 |
-
return originalFetch(String(proxiedUrl), fetchOpts);
|
| 190 |
}
|
| 191 |
|
| 192 |
const newInit = {
|
| 193 |
...init,
|
| 194 |
headers: mergedHeaders,
|
| 195 |
};
|
| 196 |
-
if (newInit.body && !newInit.duplex) {
|
| 197 |
newInit.duplex = "half";
|
| 198 |
}
|
| 199 |
|
| 200 |
-
return originalFetch(proxiedUrl, newInit);
|
| 201 |
};
|
| 202 |
}
|
| 203 |
|
|
|
|
| 21 |
PROXY_URL = `https://${PROXY_URL}`;
|
| 22 |
}
|
| 23 |
|
| 24 |
+
const DEBUG = process.env.CLOUDFLARE_PROXY_DEBUG === "true";
|
| 25 |
const PROXY_SHARED_SECRET = (process.env.CLOUDFLARE_PROXY_SECRET || "").trim();
|
| 26 |
const PROXY_DOMAINS = process.env.CLOUDFLARE_PROXY_DOMAINS || "*";
|
| 27 |
const BLOCKED_DOMAINS = PROXY_DOMAINS.split(",")
|
|
|
|
| 176 |
|
| 177 |
const proxiedUrl = new URL(url.pathname + url.search, proxy);
|
| 178 |
|
| 179 |
+
const logProxyError = (promise) => {
|
| 180 |
+
promise
|
| 181 |
+
.then(r => {
|
| 182 |
+
if (DEBUG && !r.ok) {
|
| 183 |
+
log(`[cloudflare-proxy] Proxy HTTP ${r.status} for ${hostname}: ${r.statusText}`);
|
| 184 |
+
}
|
| 185 |
+
})
|
| 186 |
+
.catch(err => {
|
| 187 |
+
const cause = err?.cause;
|
| 188 |
+
const causeStr = cause
|
| 189 |
+
? ` | cause: ${cause?.code || cause?.message || String(cause)}`
|
| 190 |
+
: "";
|
| 191 |
+
log(`[cloudflare-proxy] Proxy FAILED ${hostname}: ${err?.message}${causeStr}`);
|
| 192 |
+
});
|
| 193 |
+
return promise;
|
| 194 |
+
};
|
| 195 |
+
|
| 196 |
if (request) {
|
| 197 |
const fetchOpts = {
|
| 198 |
method: request.method,
|
|
|
|
| 203 |
fetchOpts.body = request.body;
|
| 204 |
fetchOpts.duplex = "half";
|
| 205 |
}
|
| 206 |
+
return logProxyError(originalFetch(String(proxiedUrl), fetchOpts));
|
| 207 |
}
|
| 208 |
|
| 209 |
const newInit = {
|
| 210 |
...init,
|
| 211 |
headers: mergedHeaders,
|
| 212 |
};
|
| 213 |
+
if (newInit.body instanceof ReadableStream && !newInit.duplex) {
|
| 214 |
newInit.duplex = "half";
|
| 215 |
}
|
| 216 |
|
| 217 |
+
return logProxyError(originalFetch(String(proxiedUrl), newInit));
|
| 218 |
};
|
| 219 |
}
|
| 220 |
|
start.sh
CHANGED
|
@@ -132,25 +132,13 @@ mkdir -p /home/node/.openclaw/workspace
|
|
| 132 |
chmod 700 /home/node/.openclaw
|
| 133 |
chmod 700 /home/node/.openclaw/credentials
|
| 134 |
|
| 135 |
-
# ββ Validate HF token (if provided) ββ
|
| 136 |
-
if [ -n "${HF_TOKEN:-}" ]; then
|
| 137 |
-
echo "π Validating HF token..."
|
| 138 |
-
HF_AUTH_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $HF_TOKEN" https://huggingface.co/api/repos/create --max-time 10 2>/dev/null || echo "000")
|
| 139 |
-
if [ "$HF_AUTH_STATUS" = "401" ]; then
|
| 140 |
-
echo " β οΈ HF token is invalid or expired! Workspace backup will not work."
|
| 141 |
-
echo " Get a new token: https://huggingface.co/settings/tokens"
|
| 142 |
-
else
|
| 143 |
-
echo " β
HF token is valid"
|
| 144 |
-
fi
|
| 145 |
-
fi
|
| 146 |
-
|
| 147 |
# ββ Restore workspace/state from HF Dataset ββ
|
| 148 |
BACKUP_DATASET="${BACKUP_DATASET_NAME:-huggingclaw-backup}"
|
| 149 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 150 |
-
echo "
|
| 151 |
python3 /home/node/app/workspace-sync.py restore || true
|
| 152 |
else
|
| 153 |
-
echo "HF_TOKEN
|
| 154 |
fi
|
| 155 |
|
| 156 |
CLOUDFLARE_WORKERS_TOKEN="${CLOUDFLARE_WORKERS_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}"
|
|
@@ -159,11 +147,10 @@ CF_PROXY_ENV_FILE="/tmp/huggingclaw-cloudflare-proxy.env"
|
|
| 159 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] || [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 160 |
export CLOUDFLARE_PROXY_DOMAINS="${CLOUDFLARE_PROXY_DOMAINS:-api.telegram.org,web.whatsapp.com,googleapis.com}"
|
| 161 |
export CLOUDFLARE_PROXY_DEBUG="${CLOUDFLARE_PROXY_DEBUG:-true}"
|
| 162 |
-
echo "
|
| 163 |
python3 /home/node/app/cloudflare-proxy-setup.py || true
|
| 164 |
if [ -f "$CF_PROXY_ENV_FILE" ]; then
|
| 165 |
. "$CF_PROXY_ENV_FILE"
|
| 166 |
-
echo " β
Proxy environment loaded: ${CLOUDFLARE_PROXY_URL:-none}"
|
| 167 |
fi
|
| 168 |
fi
|
| 169 |
|
|
@@ -403,59 +390,33 @@ export NODE_OPTIONS="${NODE_OPTIONS:+$NODE_OPTIONS }--require /home/node/app/ifr
|
|
| 403 |
|
| 404 |
# ββ Startup Summary ββ
|
| 405 |
echo ""
|
| 406 |
-
echo "
|
| 407 |
-
echo "
|
| 408 |
-
echo " ββββββββββββββββββββββββββββββββββββββββββββ€"
|
| 409 |
-
printf " β %-40s β\n" "OpenClaw: $OPENCLAW_DISPLAY_VERSION"
|
| 410 |
-
printf " β %-40s β\n" "Model: $LLM_MODEL"
|
| 411 |
if [ -n "${TELEGRAM_BOT_TOKEN:-}" ]; then
|
| 412 |
-
|
| 413 |
else
|
| 414 |
-
|
| 415 |
fi
|
| 416 |
if [ "$WHATSAPP_ENABLED_NORMALIZED" = "true" ]; then
|
| 417 |
-
|
| 418 |
else
|
| 419 |
-
|
| 420 |
-
fi
|
| 421 |
-
if [ "$BROWSER_SHOULD_ENABLE" = "true" ]; then
|
| 422 |
-
printf " β %-40s β\n" "Browser: β
${BROWSER_EXECUTABLE_PATH}"
|
| 423 |
-
elif [ -n "$BROWSER_EXECUTABLE_PATH" ] && [ -x "$BROWSER_EXECUTABLE_PATH" ]; then
|
| 424 |
-
printf " β %-40s β\n" "Browser: βΈ disabled (${BROWSER_PLUGIN_MODE})"
|
| 425 |
-
else
|
| 426 |
-
printf " β %-40s β\n" "Browser: β unavailable"
|
| 427 |
fi
|
| 428 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 429 |
-
|
| 430 |
else
|
| 431 |
-
|
| 432 |
fi
|
| 433 |
if [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 434 |
-
|
| 435 |
-
fi
|
| 436 |
-
if [ -n "${OPENCLAW_PASSWORD:-}" ]; then
|
| 437 |
-
printf " β %-40s β\n" "Auth: π password"
|
| 438 |
-
else
|
| 439 |
-
printf " β %-40s β\n" "Auth: π token"
|
| 440 |
fi
|
| 441 |
if [ -n "${SPACE_HOST:-}" ]; then
|
| 442 |
-
|
| 443 |
-
printf " β %-40s β\n" "Dashboard: https://${SPACE_HOST}"
|
| 444 |
-
fi
|
| 445 |
-
SYNC_STATUS="β disabled"
|
| 446 |
-
if [ -n "${HF_TOKEN:-}" ]; then
|
| 447 |
-
SYNC_STATUS="β
every ${SYNC_INTERVAL:-180}s"
|
| 448 |
-
fi
|
| 449 |
-
printf " β %-40s β\n" "Auto-sync: $SYNC_STATUS"
|
| 450 |
-
if [ -n "${WEBHOOK_URL:-}" ]; then
|
| 451 |
-
printf " β %-40s β\n" "Webhooks: β
enabled"
|
| 452 |
fi
|
| 453 |
-
echo " ββββββββββββββββββββββββββββββββββββββββββββ"
|
| 454 |
echo ""
|
| 455 |
|
| 456 |
# ββ Trigger Webhook on Restart ββ
|
| 457 |
if [ -n "${WEBHOOK_URL:-}" ]; then
|
| 458 |
-
echo "π Sending restart webhook..."
|
| 459 |
curl -s -X POST "$WEBHOOK_URL" \
|
| 460 |
-H "Content-Type: application/json" \
|
| 461 |
-d '{"event":"restart", "status":"success", "message":"HuggingClaw gateway has started/restarted.", "model": "'"$LLM_MODEL"'"}' >/dev/null 2>&1 &
|
|
@@ -463,18 +424,13 @@ fi
|
|
| 463 |
|
| 464 |
# ββ Trap SIGTERM for graceful shutdown οΏ½οΏ½οΏ½β
|
| 465 |
graceful_shutdown() {
|
| 466 |
-
echo ""
|
| 467 |
-
echo "π Shutting down gracefully..."
|
| 468 |
-
|
| 469 |
if [ -f "/home/node/app/workspace-sync.py" ]; then
|
| 470 |
-
echo "
|
| 471 |
python3 /home/node/app/workspace-sync.py sync-once || \
|
| 472 |
-
echo "
|
| 473 |
fi
|
| 474 |
-
|
| 475 |
-
# Kill background processes
|
| 476 |
kill $(jobs -p) 2>/dev/null
|
| 477 |
-
echo "π Goodbye!"
|
| 478 |
exit 0
|
| 479 |
}
|
| 480 |
trap graceful_shutdown SIGTERM SIGINT
|
|
@@ -506,13 +462,12 @@ node /home/node/app/health-server.js &
|
|
| 506 |
HEALTH_PID=$!
|
| 507 |
|
| 508 |
# ββ Launch gateway ββ
|
| 509 |
-
echo "
|
| 510 |
-
echo ""
|
| 511 |
|
| 512 |
GATEWAY_ARGS=(gateway run --port 7860 --bind lan)
|
| 513 |
if [ "${GATEWAY_VERBOSE:-0}" = "1" ]; then
|
| 514 |
GATEWAY_ARGS+=(--verbose)
|
| 515 |
-
echo "
|
| 516 |
fi
|
| 517 |
|
| 518 |
# Use stdbuf -oL -eL to ensure logs are not buffered and appear immediately in the console
|
|
@@ -533,7 +488,7 @@ fi
|
|
| 533 |
if [ "$WHATSAPP_ENABLED_NORMALIZED" = "true" ]; then
|
| 534 |
node /home/node/app/wa-guardian.js &
|
| 535 |
GUARDIAN_PID=$!
|
| 536 |
-
echo "
|
| 537 |
fi
|
| 538 |
|
| 539 |
# 11.5 Warm up the managed browser so first browser actions have a live tab
|
|
|
|
| 132 |
chmod 700 /home/node/.openclaw
|
| 133 |
chmod 700 /home/node/.openclaw/credentials
|
| 134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
# ββ Restore workspace/state from HF Dataset ββ
|
| 136 |
BACKUP_DATASET="${BACKUP_DATASET_NAME:-huggingclaw-backup}"
|
| 137 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 138 |
+
echo "Restoring workspace from HF Dataset..."
|
| 139 |
python3 /home/node/app/workspace-sync.py restore || true
|
| 140 |
else
|
| 141 |
+
echo "HF_TOKEN not set β running without dataset persistence."
|
| 142 |
fi
|
| 143 |
|
| 144 |
CLOUDFLARE_WORKERS_TOKEN="${CLOUDFLARE_WORKERS_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}"
|
|
|
|
| 147 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] || [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 148 |
export CLOUDFLARE_PROXY_DOMAINS="${CLOUDFLARE_PROXY_DOMAINS:-api.telegram.org,web.whatsapp.com,googleapis.com}"
|
| 149 |
export CLOUDFLARE_PROXY_DEBUG="${CLOUDFLARE_PROXY_DEBUG:-true}"
|
| 150 |
+
echo "Preparing Cloudflare outbound proxy..."
|
| 151 |
python3 /home/node/app/cloudflare-proxy-setup.py || true
|
| 152 |
if [ -f "$CF_PROXY_ENV_FILE" ]; then
|
| 153 |
. "$CF_PROXY_ENV_FILE"
|
|
|
|
| 154 |
fi
|
| 155 |
fi
|
| 156 |
|
|
|
|
| 390 |
|
| 391 |
# ββ Startup Summary ββ
|
| 392 |
echo ""
|
| 393 |
+
echo "Version : ${OPENCLAW_DISPLAY_VERSION}"
|
| 394 |
+
echo "Model : ${LLM_MODEL}"
|
|
|
|
|
|
|
|
|
|
| 395 |
if [ -n "${TELEGRAM_BOT_TOKEN:-}" ]; then
|
| 396 |
+
echo "Telegram : enabled"
|
| 397 |
else
|
| 398 |
+
echo "Telegram : not configured"
|
| 399 |
fi
|
| 400 |
if [ "$WHATSAPP_ENABLED_NORMALIZED" = "true" ]; then
|
| 401 |
+
echo "WhatsApp : enabled"
|
| 402 |
else
|
| 403 |
+
echo "WhatsApp : disabled"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 404 |
fi
|
| 405 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 406 |
+
echo "Backup : ${BACKUP_DATASET:-huggingclaw-backup} (every ${SYNC_INTERVAL:-180}s)"
|
| 407 |
else
|
| 408 |
+
echo "Backup : disabled"
|
| 409 |
fi
|
| 410 |
if [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 411 |
+
echo "Proxy : ${CLOUDFLARE_PROXY_URL}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
fi
|
| 413 |
if [ -n "${SPACE_HOST:-}" ]; then
|
| 414 |
+
echo "Control UI: https://${SPACE_HOST}/app"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
fi
|
|
|
|
| 416 |
echo ""
|
| 417 |
|
| 418 |
# ββ Trigger Webhook on Restart ββ
|
| 419 |
if [ -n "${WEBHOOK_URL:-}" ]; then
|
|
|
|
| 420 |
curl -s -X POST "$WEBHOOK_URL" \
|
| 421 |
-H "Content-Type: application/json" \
|
| 422 |
-d '{"event":"restart", "status":"success", "message":"HuggingClaw gateway has started/restarted.", "model": "'"$LLM_MODEL"'"}' >/dev/null 2>&1 &
|
|
|
|
| 424 |
|
| 425 |
# ββ Trap SIGTERM for graceful shutdown οΏ½οΏ½οΏ½β
|
| 426 |
graceful_shutdown() {
|
| 427 |
+
echo "Shutting down..."
|
|
|
|
|
|
|
| 428 |
if [ -f "/home/node/app/workspace-sync.py" ]; then
|
| 429 |
+
echo "Saving state before exit..."
|
| 430 |
python3 /home/node/app/workspace-sync.py sync-once || \
|
| 431 |
+
echo "Warning: could not complete shutdown sync"
|
| 432 |
fi
|
|
|
|
|
|
|
| 433 |
kill $(jobs -p) 2>/dev/null
|
|
|
|
| 434 |
exit 0
|
| 435 |
}
|
| 436 |
trap graceful_shutdown SIGTERM SIGINT
|
|
|
|
| 462 |
HEALTH_PID=$!
|
| 463 |
|
| 464 |
# ββ Launch gateway ββ
|
| 465 |
+
echo "Launching OpenClaw gateway on port 7860..."
|
|
|
|
| 466 |
|
| 467 |
GATEWAY_ARGS=(gateway run --port 7860 --bind lan)
|
| 468 |
if [ "${GATEWAY_VERBOSE:-0}" = "1" ]; then
|
| 469 |
GATEWAY_ARGS+=(--verbose)
|
| 470 |
+
echo "Gateway verbose logging enabled (GATEWAY_VERBOSE=1)"
|
| 471 |
fi
|
| 472 |
|
| 473 |
# Use stdbuf -oL -eL to ensure logs are not buffered and appear immediately in the console
|
|
|
|
| 488 |
if [ "$WHATSAPP_ENABLED_NORMALIZED" = "true" ]; then
|
| 489 |
node /home/node/app/wa-guardian.js &
|
| 490 |
GUARDIAN_PID=$!
|
| 491 |
+
echo "WhatsApp Guardian started (PID: $GUARDIAN_PID)"
|
| 492 |
fi
|
| 493 |
|
| 494 |
# 11.5 Warm up the managed browser so first browser actions have a live tab
|