close
Skip to content

[Duplicate Code] Near-duplicate HTTP request setup in model-discovery.js fetchJson vs httpProbe #2609

@github-actions

Description

@github-actions

Duplicate Code Opportunity

Summary

  • Pattern: fetchJson and httpProbe in containers/api-proxy/model-discovery.js share ~25 lines of identical HTTP/HTTPS request setup code (URL parsing, reqOpts construction, settled/resolveOnce pattern, req.on('timeout', ...), req.on('error', ...)). The only differences are in response handling.
  • Locations: containers/api-proxy/model-discovery.js lines ~46–59 (fetchJson) and ~100–113 (httpProbe)
  • Impact: Any change to proxy agent configuration, timeout handling, or error logging in request setup must be made in both functions.

Evidence

fetchJson setup (lines ~46–72):

const parsed = new URL(url);
const isHttps = parsed.protocol === 'https:';
const mod = isHttps ? https : http;
const reqOpts = {
  hostname: parsed.hostname,
  port: parsed.port || (isHttps ? 443 : 80),
  path: parsed.pathname + parsed.search,
  method: opts.method,
  headers: { ...opts.headers },
  ...(isHttps && proxyAgent ? { agent: proxyAgent } : {}),
  timeout: timeoutMs,
};
let settled = false;
const resolveOnce = (value) => { if (settled) return; settled = true; resolve(value); };
const req = mod.request(reqOpts, (res) => { ... });
req.on('timeout', () => { req.destroy(...); });
req.on('error', (err) => { resolveOnce(null); });
req.end();

httpProbe setup (lines ~100–126) is structurally identical — same URL parsing, same reqOpts, same settled/resolveOnce/rejectOnce pattern.

Suggested Refactoring

Extract a buildRequest(url, opts, timeoutMs, onResponse) helper that handles the shared setup:

function buildRequest(url, opts, timeoutMs, onResponse) {
  const parsed = new URL(url);
  const isHttps = parsed.protocol === 'https:';
  const mod = isHttps ? https : http;
  const reqOpts = {
    hostname: parsed.hostname,
    port: parsed.port || (isHttps ? 443 : 80),
    path: parsed.pathname + parsed.search,
    method: opts.method,
    headers: { ...opts.headers },
    ...(isHttps && proxyAgent ? { agent: proxyAgent } : {}),
    timeout: timeoutMs,
  };
  return { mod, reqOpts };
}

Both fetchJson and httpProbe call buildRequest for setup, then differ only in onResponse logic.

Affected Files

  • containers/api-proxy/model-discovery.jsfetchJson (~lines 46–95) and httpProbe (~lines 100–130)

Effort Estimate

Low


Detected by Duplicate Code Detector workflow. Run date: 2026-05-06

Generated by Duplicate Code Detector · ● 564K ·

  • expires on Jun 5, 2026, 5:02 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions