{"record":{"id":"41e618c1164f64f6","repo":"decolua/9router","slug":"unhandled-error-e-message","errorCode":null,"errorMessage":"Unhandled error: ${e.message}","messagePattern":"Unhandled error: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/mitm/server.js","lineNumber":339,"sourceCode":"    }\n\n    const model = extractModel(req.url, bodyBuffer);\n\n    // Intentional passthrough: some models must never be re-routed (e.g. Antigravity\n    // tab-autocomplete) so latency-critical inline completion stays native. Silent — this\n    // is by design, not a leak, and fires per keystroke. See MODEL_NO_MAP in config.js.\n    if (model && (MODEL_NO_MAP[tool] || []).some((re) => re.test(model))) {\n      return passthrough(req, res, bodyBuffer);\n    }\n\n    const mappedModel = getMappedModel(tool, model);\n    if (!mappedModel) {\n      return passthrough(req, res, bodyBuffer);\n    }\n\n    return handlers[tool].intercept(req, res, bodyBuffer, mappedModel, passthrough);\n  } catch (e) {\n    err(`Unhandled error: ${e.message}`);\n    if (!res.headersSent) res.writeHead(500, { \"Content-Type\": \"application/json\" });\n    res.end(JSON.stringify({ error: { message: e.message, type: \"mitm_error\" } }));\n  }\n});\n\n// Kill only processes LISTENING on LOCAL_PORT (not outbound connections)\nfunction killPort(port) {\n  try {\n    let pidList = [];\n    if (IS_WIN) {\n      const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command ` +\n        `\"Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess\"`;\n      const out = execSync(psCmd, { encoding: \"utf-8\", windowsHide: true }).trim();\n      if (!out) return;\n      pidList = out.split(/\\r?\\n/).map(s => s.trim()).filter(p => p && Number(p) !== process.pid && Number(p) > 4);\n    } else {\n      const out = execSync(`${LSOF_BIN} -nP -iTCP:${port} -sTCP:LISTEN -t`, { encoding: \"utf-8\", windowsHide: true }).trim();\n      if (!out) return;","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/server.js#L321-L357","documentation":"Top-level catch of the MITM server's request handler. After DNS interception, body reading and model mapping, a recognized tool dispatches to its handler's intercept(); any synchronous or awaited throw outside the per-handler catches lands here, logged 'Unhandled error: <message>' and answered with a 500 JSON { message, type: 'mitm_error' }.","triggerScenarios":"Handler dispatch throws before the per-tool try/catch: unknown tool name lookup, bodyBuffer read failure, model-map resolution throwing, or a handler module that itself throws synchronously (e.g. missing export).","commonSituations":"A tool not in the handlers map but also failing the passthrough path; model mapping table missing an entry and the mapper throwing instead of returning null; partially built/edited custom handler exporting a broken intercept.","solutions":["Read the logged message to identify which stage threw (mapping vs dispatch vs handler).","Add/fix the model mapping so resolution returns null (→ passthrough) instead of throwing.","Verify the tool's handler module exists and exports { intercept }.","If the tool should not be intercepted, ensure it falls through to passthrough rather than the handlers map."],"exampleFix":"// before\nconst mappedModel = modelMap[tool][reqModel]; // throws if table missing\n// after\nconst mappedModel = modelMap[tool]?.[reqModel] ?? null; // null → passthrough","handlingStrategy":"validation","validationCode":"// guard dispatch inputs before invoking the handler\nif (typeof handlers[tool]?.intercept !== 'function') return passthrough(req, res, bodyBuffer);\nconst mappedModel = modelMap[tool]?.[requestedModel] ?? null;\nif (typeof mappedModel !== 'string') return passthrough(req, res, bodyBuffer);","typeGuard":"function hasIntercept(h) {\n  return h !== null && typeof h === 'object' && typeof h.intercept === 'function';\n}","tryCatchPattern":"try {\n  if (!hasIntercept(handlers[tool])) return passthrough(req, res, bodyBuffer);\n  return handlers[tool].intercept(req, res, bodyBuffer, mappedModel, passthrough);\n} catch (e) {\n  err(`Unhandled error: ${e.message}`);\n  if (!res.headersSent) res.writeHead(500, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ error: { message: e.message, type: 'mitm_error' } }));\n}","preventionTips":["Use optional chaining on model-map lookups so unknown models fall through to passthrough.","Validate handler modules export { intercept } at startup, not per-request.","Keep tools that should not be intercepted out of the handlers map.","Log unhandled errors with the tool name and URL for faster triage."],"tags":["mitm","unhandled-exception","model-mapping"],"backgroundTag":"mitm-proxy-request-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}