{"record":{"id":"434481e0b569fef3","repo":"agalwood/Motrix","slug":"plugin-http-network","errorCode":"plugin.http.network","errorMessage":"Network error: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Network error: (.+?)","errorType":"exception","errorClass":"HttpError","httpStatus":null,"severity":"error","filePath":"src/core/plugin/capabilities/http.ts","lineNumber":358,"sourceCode":"              throw new HttpError(\n                'plugin.http.aborted',\n                'Request aborted by plugin'\n              )\n            }\n            throw new HttpError('plugin.http.aborted', 'Request aborted')\n          }\n          if (\n            err instanceof Error &&\n            (err.name === 'AbortError' ||\n              err.name === 'DOMException' ||\n              err.constructor?.name === 'DOMException')\n          ) {\n            throw new HttpError(\n              'plugin.http.aborted',\n              'Request aborted by plugin'\n            )\n          }\n          throw new HttpError(\n            'plugin.http.network',\n            `Network error: ${err instanceof Error ? err.message : String(err)}`\n          )\n        }\n\n        // Capture cookies from response on this hop.\n        if (useCookies && this.cookieJar) {\n          const rawSetCookie = response.headers['set-cookie']\n          const arr = Array.isArray(rawSetCookie)\n            ? rawSetCookie\n            : typeof rawSetCookie === 'string'\n              ? [rawSetCookie]\n              : []\n          if (arr.length > 0) {\n            this.cookieJar.captureFromResponseHeaders(currentUrl, arr)\n          }\n        }\n","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/plugin/capabilities/http.ts#L340-L376","documentation":"Catch-all for non-abort failures from undiciRequest: DNS errors (ENOTFOUND, EAI_AGAIN), connection refused (ECONNREFUSED), TCP resets (ECONNRESET), socket hang-up, TLS/cert errors, invalid HTTP responses, and similar. The underlying message is interpolated so callers can branch on the cause while keeping one stable error code.","triggerScenarios":"DNS resolution failure; target host/port unreachable; TLS certificate invalid/expired/self-signed; connection reset mid-transfer; server returned malformed HTTP; proxy refused the CONNECT.","commonSituations":"Wrong hostname in config; firewall or network partition; clock skew causing TLS cert validity mismatch; corporate proxy not configured; IPv6-only target with no v6 route.","solutions":["Inspect err.message / cause for the specific syscall (ENOTFOUND vs ECONNRESET vs CERT_*).","Verify host, port, and DNS resolution from the runtime environment.","For TLS errors, validate the CA chain and system clock.","Configure proxy/HTTP_PROXY/HTTPS_PROXY if applicable.","Retry with backoff for transient resets."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function isTransientNetwork(err: unknown): boolean {\n  if (!(err instanceof HttpError)) return false\n  if (err.code !== 'plugin.http.network') return false\n  return /ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|socket hang up/i.test(err.message)\n}","tryCatchPattern":"for (const attempt of [1,2,3]) {\n  try {\n    return await http.request(opts)\n  } catch (e) {\n    const transient = e instanceof HttpError && e.code === 'plugin.http.network'\n    const dns = e instanceof HttpError && /ENOTFOUND|EAI_AGAIN/.test(e.message)\n    if (transient && !dns && attempt < 3) { await sleep(2 ** attempt * 200); continue }\n    throw e\n  }\n}","preventionTips":["Inspect the interpolated message to branch on syscall (ENOTFOUND, ECONNRESET, CERT).","Retry only transient causes; do not retry DNS or TLS-cert errors.","Verify proxy env (HTTP_PROXY/HTTPS_PROXY) and DNS from the runtime, not just your laptop."],"tags":["http","network","dns","tls","connection"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}