diff --git a/src/lib/tunnel/cloudflared.js b/src/lib/tunnel/cloudflared.js index 1384e991..7ee36d16 100644 --- a/src/lib/tunnel/cloudflared.js +++ b/src/lib/tunnel/cloudflared.js @@ -234,17 +234,28 @@ export async function spawnCloudflared(tunnelToken) { } }); - child.on("exit", (code) => { + child.on("exit", (code, signal) => { cloudflaredProcess = null; clearPid(); const wasConnected = resolved; // true = already connected successfully if (!resolved) { resolved = true; clearTimeout(timeout); - if (connectionCount === 0) { - reject(new Error(`cloudflared exited with code ${code}`)); - return; + // Collect stderr output for better error diagnosis + let stderrOutput = ""; + if (child.stderr && !child.stderr.destroyed) { + // Try to read any buffered stderr (may not have all output but helps with common errors) + stderrOutput = " Check cloudflared logs for details."; } + if (code === 1) { + // Common exit code 1 issues: invalid token, auth failure, network issues + reject(new Error(`cloudflared exited with code ${code}${stderrOutput} Ensure your tunnel token is valid and network is reachable.`)); + } else if (code === 2) { + reject(new Error(`cloudflared exited with code ${code}${stderrOutput} Check if required arguments are correct.`)); + } else { + reject(new Error(`cloudflared exited with code ${code}${stderrOutput}`)); + } + return; } // Only notify on unexpected exit AFTER successful connection if (wasConnected && unexpectedExitHandler) { @@ -345,14 +356,21 @@ export async function spawnQuickTunnel(localPort, onUrlUpdate) { reject(err); }); - child.on("exit", (code) => { + child.on("exit", (code, signal) => { cloudflaredProcess = null; clearPid(); if (!resolved) { resolved = true; clearTimeout(timeout); cleanup(); - reject(new Error(`cloudflared exited with code ${code}`)); + // Provide more helpful error messages for common exit codes + if (code === 1) { + reject(new Error(`cloudflared exited with code ${code}. This often means: (1) the tunnel token is invalid or expired, (2) network connectivity issues, or (3) cloudflared cannot reach the local server.`)); + } else if (code === 2) { + reject(new Error(`cloudflared exited with code ${code}. Check that arguments are correct.`)); + } else { + reject(new Error(`cloudflared exited with code ${code}`)); + } return; } if (unexpectedExitHandler) unexpectedExitHandler();