{"record":{"id":"e81432d7f4e90f61","repo":"can1357/oh-my-pi","slug":"proxy-tunnel-aborted","errorCode":null,"errorMessage":"Proxy tunnel aborted","messagePattern":"Proxy tunnel aborted","errorType":"exception","errorClass":"AbortError","httpStatus":null,"severity":"warning","filePath":"packages/ai/src/utils/proxy.ts","lineNumber":286,"sourceCode":"\t/** Caller cancellation for the proxy TCP/TLS handshake and CONNECT tunnel. */\n\tsignal?: AbortSignal;\n\t/** Maximum wall-clock time to establish the final TLS tunnel. Disabled when absent or non-positive. */\n\ttimeoutMs?: number;\n\t/** Target TLS profile. Cursor defaults to HTTP/2 when this is absent. */\n\ttls?: tls.ConnectionOptions;\n}\n\n/**\n * Tunnel a socket connection through an HTTP CONNECT proxy.\n * This is used specifically to wrap Node's `http2.connect(baseUrl, { createConnection })` for Cursor.\n */\nexport async function connectProxiedSocket(\n\tproxyUrlStr: string,\n\ttargetUrlStr: string,\n\toptions?: ConnectProxiedSocketOptions,\n): Promise<tls.TLSSocket> {\n\tif (options?.signal?.aborted) {\n\t\tthrow new AbortError(\"Proxy tunnel aborted\");\n\t}\n\n\tconst proxyUrl = new URL(proxyUrlStr);\n\tconst targetUrl = new URL(targetUrlStr);\n\n\tconst useProxySsl = proxyUrl.protocol === \"https:\";\n\tconst proxyPort = proxyUrl.port ? parseInt(proxyUrl.port, 10) : useProxySsl ? 443 : 80;\n\tconst proxyHost = proxyUrl.hostname;\n\n\tconst targetPort = targetUrl.port ? parseInt(targetUrl.port, 10) : 443;\n\tconst targetHost = targetUrl.hostname;\n\n\tconst { promise, resolve, reject } = Promise.withResolvers<tls.TLSSocket>();\n\n\tconst readyEvent = useProxySsl ? \"secureConnect\" : \"connect\";\n\tlet rawSocket: net.Socket | undefined;\n\tlet tunnelSocket: tls.TLSSocket | undefined;\n\tlet timeout: NodeJS.Timeout | undefined;","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/utils/proxy.ts#L268-L304","documentation":"connectProxiedSocket tunnels a TLS socket through an HTTP(S) proxy (CONNECT). Before doing any work it checks the caller-supplied AbortSignal and throws AbortError('Proxy tunnel aborted') if the signal is already aborted. This is an intentional cooperative-cancellation guard: the library refuses to start a proxy handshake for an operation that has already been cancelled.","triggerScenarios":"Calling connectProxiedSocket (directly or via provider fetch/socket setup) with options.signal from an AbortController that was already aborted — e.g. a request timeout fired, the user cancelled, or a race where abort happens between controller creation and the call.","commonSituations":"Request timeouts that abort the controller before the socket connect begins; retry logic that aborts the previous attempt's signal but reuses it for the new attempt; streaming clients cancelled by the consumer while the connection was still being established; global shutdown/dispose aborting all in-flight signals.","solutions":["Check `signal?.aborted` before calling connectProxiedSocket and skip the call if already cancelled","Create a fresh AbortController per connection attempt instead of reusing an aborted one","If the abort was unintentional (timeout too aggressive), raise the timeout that triggers controller.abort()","Handle AbortError distinctly from network failures — do not retry it as a transient error; treat as cancellation"],"exampleFix":"// before — reusing a possibly-aborted controller\nconst socket = await connectProxiedSocket(proxyUrl, targetUrl, { signal: controller.signal });\n// after — fresh signal per attempt, bail out early\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), timeoutMs);\nif (controller.signal.aborted) return;\nconst socket = await connectProxiedSocket(proxyUrl, targetUrl, { signal: controller.signal });","handlingStrategy":"try-catch","validationCode":"if (options?.signal?.aborted) {\n  throw new DOMException(\"Aborted before proxy connect\", \"AbortError\");\n}","typeGuard":"function isAbortError(err: unknown): err is Error {\n  return err instanceof Error && (err.name === \"AbortError\" || err.message.includes(\"aborted\"));\n}","tryCatchPattern":"try {\n  const socket = await connectProxiedSocket(proxy, target, { signal });\n} catch (err) {\n  if (isAbortError(err)) return; // cancellation, not a failure — do not retry\n  throw err;\n}","preventionTips":["Check signal.aborted before initiating each connection attempt","Use one fresh AbortController per attempt, never recycle aborted signals","Distinguish AbortError from network errors in your retry policy","Keep timeout-driven aborts aligned with expected proxy handshake latency"],"tags":["proxy","abort","tls","network"],"backgroundTag":"abort-signal-aborted","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}