Duplicate Code Opportunity
Summary
- Pattern: Three nearly-identical error-handling + metrics + logging blocks inside
proxyRequest() and proxyWebSocket() in containers/api-proxy/proxy-request.js
- Locations: Lines 201–213, 358–367, 421–433 of
containers/api-proxy/proxy-request.js
- Impact: ~36 lines of near-duplicate error handling; any change to the log schema or metrics API must be made in three places, creating drift risk in a security-relevant logging path
Evidence
Block 1 — client request error (lines 201–213):
req.on('error', (err) => {
if (errored) return;
errored = true;
const duration = Date.now() - startTime;
metrics.gaugeDec('active_requests', { provider });
metrics.increment('requests_errors_total', { provider });
logRequest('error', 'request_error', {
request_id: requestId, provider, method: req.method,
path: sanitizeForLog(req.url), duration_ms: duration,
error: sanitizeForLog(err.message), upstream_host: targetHost,
});
if (!res.headersSent) res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Client error', message: err.message }));
});
Block 2 — proxy response stream error (lines 358–368):
proxyRes.on('error', (err) => {
const duration = Date.now() - startTime;
metrics.gaugeDec('active_requests', { provider });
metrics.increment('requests_errors_total', { provider });
logRequest('error', 'request_error', {
request_id: requestId, provider, method: req.method,
path: sanitizeForLog(req.url), duration_ms: duration,
error: sanitizeForLog(err.message), upstream_host: targetHost,
});
if (!res.headersSent) res.writeHead(502, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Response stream error', message: err.message }));
});
Block 3 — upstream proxy request error (lines 421–433):
proxyReq.on('error', (err) => {
const duration = Date.now() - startTime;
metrics.gaugeDec('active_requests', { provider });
metrics.increment('requests_errors_total', { provider });
metrics.increment('requests_total', { provider, method: req.method, status_class: '5xx' });
metrics.observe('request_duration_ms', duration, { provider });
logRequest('error', 'request_error', {
request_id: requestId, provider, method: req.method,
path: sanitizeForLog(req.url), duration_ms: duration,
error: sanitizeForLog(err.message), upstream_host: targetHost,
});
if (!res.headersSent) res.writeHead(502, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Proxy error', message: err.message }));
});
Suggested Refactoring
Extract a helper function in containers/api-proxy/proxy-request.js:
function handleRequestError(err, { res, requestId, provider, req, targetHost, startTime, statusCode, clientMessage, extraMetrics }) {
const duration = Date.now() - startTime;
metrics.gaugeDec('active_requests', { provider });
metrics.increment('requests_errors_total', { provider });
if (extraMetrics) extraMetrics(duration);
logRequest('error', 'request_error', {
request_id: requestId, provider, method: req.method,
path: sanitizeForLog(req.url), duration_ms: duration,
error: sanitizeForLog(err.message), upstream_host: targetHost,
});
if (!res.headersSent) res.writeHead(statusCode, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: clientMessage, message: err.message }));
}
Each error handler then becomes a one-liner call. This is especially important because the logRequest call is on the security audit logging path — fields logged here appear in the firewall's access audit trail.
Affected Files
containers/api-proxy/proxy-request.js — lines 201–213, 358–367, 421–433
Effort Estimate
Low — pure internal refactor within one file, well-covered by existing server.proxy.test.js tests.
Detected by Duplicate Code Detector workflow. Run date: 2026-05-17
Generated by Duplicate Code Detector · ● 8M · ◷
Duplicate Code Opportunity
Summary
proxyRequest()andproxyWebSocket()incontainers/api-proxy/proxy-request.jscontainers/api-proxy/proxy-request.jsEvidence
Block 1 — client request error (lines 201–213):
Block 2 — proxy response stream error (lines 358–368):
Block 3 — upstream proxy request error (lines 421–433):
Suggested Refactoring
Extract a helper function in
containers/api-proxy/proxy-request.js:Each error handler then becomes a one-liner call. This is especially important because the
logRequestcall is on the security audit logging path — fields logged here appear in the firewall's access audit trail.Affected Files
containers/api-proxy/proxy-request.js— lines 201–213, 358–367, 421–433Effort Estimate
Low — pure internal refactor within one file, well-covered by existing
server.proxy.test.jstests.Detected by Duplicate Code Detector workflow. Run date: 2026-05-17