web: add reconnect logging + troubleshooting doc

This commit is contained in:
Peter Steinberger
2025-11-26 02:41:10 +01:00
parent 765d67cd18
commit 5992e629c3
3 changed files with 62 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ Context: `src/provider-web.ts` was a 900+ line ball of mud mixing session manage
- Bounded reconnects: web relay uses capped exponential backoff (default 2s→30s, max 12 attempts). CLI knobs `--web-retries`, `--web-retry-initial`, `--web-retry-max`, `--web-heartbeat` and config `web.reconnect`/`web.heartbeatSeconds` tune the behavior.
- Backoff reset after healthy uptime; logged-out state still exits immediately.
- Extracted reconnect/heartbeat helpers to `src/web/reconnect.ts` with unit tests.
- Added troubleshooting guide at `docs/refactor/web-relay-troubleshooting.md` (common errors, knobs, logs).
## How to use
- Link: `warelay login --provider web`

View File

@@ -0,0 +1,31 @@
# Web Relay Troubleshooting (Nov 26, 2025)
## Symptoms & quick fixes
- **Stream Errored / Conflict / status 409515:** WhatsApp closed the socket because another session is active or creds went stale. Run `warelay logout` then `warelay login --provider web` and restart the relay.
- **Logged out:** Console prints “session logged out”; re-link with `warelay login --provider web`.
- **Repeated retries then exit:** Reconnects are capped (default 12 attempts). Tune with `--web-retries`, `--web-retry-initial`, `--web-retry-max`, or config `web.reconnect`.
- **No inbound messages:** Ensure the QR-linked account is online in WhatsApp, and check logs for `web-heartbeat` to confirm auth age/connection.
## Helpful commands
- Start relay web-only: `pnpm warelay relay --provider web --verbose`
- Show who is linked: `pnpm warelay relay --provider web --verbose` (first line prints the linked E.164)
- Logout (clear creds): `pnpm warelay logout`
- Relink: `pnpm warelay login --provider web`
- Tail logs (default): `tail -f /tmp/warelay/warelay.log`
## Reading the logs
- `web-reconnect`: close reasons, retry/backoff, max-attempt exit.
- `web-heartbeat`: connectionId, messagesHandled, authAgeMs, uptimeMs (every 60s by default).
- `web-auto-reply`: inbound/outbound message records with correlation IDs.
## When to tweak knobs
- High churn networks: increase `web.reconnect.maxAttempts` or `--web-retries`.
- Slow links: raise `--web-retry-max` to give more headroom before bailing.
- Chatty monitors: increase `--web-heartbeat` interval if log volume is high.
## If it keeps failing
1) `warelay logout``warelay login --provider web` (fresh QR link).
2) Ensure no other device/browser is using the same WA Web session.
3) Check WhatsApp mobile app is online and not in low-power mode.
4) If status is 515, let the client restart once after pairing (already handled automatically).
5) Capture the last `web-reconnect` entry and the status code before escalating.

View File

@@ -40,6 +40,7 @@ export async function monitorWebProvider(
const runId = newConnectionId();
const replyLogger = getChildLogger({ module: "web-auto-reply", runId });
const heartbeatLogger = getChildLogger({ module: "web-heartbeat", runId });
const reconnectLogger = getChildLogger({ module: "web-reconnect", runId });
const cfg = loadConfig();
const configuredMaxMb = cfg.inbound?.reply?.mediaMaxMb;
const maxMediaBytes =
@@ -319,6 +320,16 @@ export async function monitorWebProvider(
"isLoggedOut" in reason &&
(reason as { isLoggedOut?: boolean }).isLoggedOut;
reconnectLogger.info(
{
connectionId,
status,
loggedOut,
reconnectAttempts,
},
"web reconnect: connection closed",
);
if (loggedOut) {
runtime.error(
danger(
@@ -334,6 +345,15 @@ export async function monitorWebProvider(
reconnectPolicy.maxAttempts > 0 &&
reconnectAttempts >= reconnectPolicy.maxAttempts
) {
reconnectLogger.warn(
{
connectionId,
status,
reconnectAttempts,
maxAttempts: reconnectPolicy.maxAttempts,
},
"web reconnect: max attempts reached",
);
runtime.error(
danger(
`WhatsApp Web connection closed (status ${status}). Reached max retries (${reconnectPolicy.maxAttempts}); exiting so you can relink.`,
@@ -344,6 +364,16 @@ export async function monitorWebProvider(
}
const delay = computeBackoff(reconnectPolicy, reconnectAttempts);
reconnectLogger.info(
{
connectionId,
status,
reconnectAttempts,
maxAttempts: reconnectPolicy.maxAttempts || "unlimited",
delayMs: delay,
},
"web reconnect: scheduling retry",
);
runtime.error(
danger(
`WhatsApp Web connection closed (status ${status}). Retry ${reconnectAttempts}/${reconnectPolicy.maxAttempts || "∞"} in ${formatDuration(delay)}`,