// Human-readable classification only. Do not log credentials, headers, or bodies. export function classifyTransportError(error) { const message = String(error instanceof Error ? error.message : error || "Unknown error"); if (/\b(?:401|403)\b|AUTH_REQUIRED|ORIGIN_BLOCKED|TARGET_BLOCKED|forbidden|blocked by policy|refusing to create a stream/i.test(message)) { return {category:"Policy/auth", suggestion:"Check the local destination allowlist and the relay session. Do not retry blocked account checks."}; } if (/\b429\b|rate.?limit|throttl|ConnThrottled/i.test(message)) { return {category:"Rate/stream limit", suggestion:"Reduce concurrent requests or wait before retrying."}; } if (/service worker|worker origin|scramjet|controller|404.*proxy/i.test(message)) { return {category:"Service worker", suggestion:"Reload the proxy page and verify that Scramjet has a controlling service worker."}; } if (/SSL|TLS|certificate|curl.*(?:35|60)|handshake.*(?:ssl|tls)/i.test(message)) { return {category:"TLS", suggestion:"Check that the Wisp connection stays up and the destination certificate is valid."}; } if (/ENOTFOUND|EAI_AGAIN|resolve host|dns|name resolution/i.test(message)) { return {category:"DNS", suggestion:"Check the destination hostname and local network DNS."}; } if (/websocket|\bwisp\b|socket closed|socket error|ws connection/i.test(message)) { return {category:"WebSocket/Wisp", suggestion:"Check the Wisp server terminal and whether port 3100 is listening."}; } if (/ECONNREFUSED|ECONNRESET|connect to server|connection refused|could not connect|network unreachable|curl.*7/i.test(message)) { return {category:"TCP/network", suggestion:"Check the Wisp server, allowed destination host, and network connectivity."}; } if (/timeout|timed out|abort/i.test(message)) { return {category:"Timeout", suggestion:"The request exceeded its deadline; inspect server logs and retry once."}; } if (/\b(?:400|404|500|502|503)\b|HTTP status|upstream/i.test(message)) { return {category:"HTTP/application", suggestion:"Inspect the upstream HTTP status; it is not necessarily a transport failure."}; } return {category:"Other", suggestion:"Inspect the browser console and Wisp server output for the first error."}; }