{"record":{"id":"0f1463309fea3c85","repo":"datawhalechina/hello-agents","slug":"resp-status","errorCode":null,"errorMessage":"计划模式请求失败: ${resp.status}","messagePattern":"计划模式请求失败: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"Co-creation-projects/usernamedadad-AutoFlow/frontend/src/services/api.js","lineNumber":11,"sourceCode":"const API_BASE = import.meta.env.VITE_API_BASE_URL || \"\";\n\nexport async function buildPlan(text, direction = \"TD\") {\n  const resp = await fetch(`${API_BASE}/api/plan`, {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({ text, direction }),\n  });\n\n  if (!resp.ok) {\n    throw new Error(`计划模式请求失败: ${resp.status}`);\n  }\n\n  return resp.json();\n}\n\nfunction parseSSEChunk(buffer, onEvent) {\n  const parts = buffer.split(\"\\n\\n\");\n  const remaining = parts.pop() || \"\";\n\n  for (const block of parts) {\n    const lines = block.split(\"\\n\");\n    let eventType = \"message\";\n    let dataLine = \"\";\n\n    for (const line of lines) {\n      if (line.startsWith(\"event:\")) {\n        eventType = line.slice(6).trim();\n      }","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/usernamedadad-AutoFlow/frontend/src/services/api.js#L1-L29","documentation":"Thrown by buildPlan() in the AutoFlow frontend when the POST to /api/plan returns a non-2xx HTTP status. The fetch API does not throw on HTTP errors, so this manual check is the only signal that the plan-generation backend rejected the request. The message embeds only the numeric status code (e.g. '计划模式请求失败: 500' (plan mode request failed: 500)), which is the sole diagnostic available because the response body is discarded.","triggerScenarios":"POST {API_BASE}/api/plan with body {text, direction} returns 4xx/5xx: 404 when API_BASE (from VITE_API_BASE_URL) points at the wrong host or the backend route is missing, 422 when text/direction fail backend validation (direction must be 'TD'/'BU' etc.), 500 when the downstream LLM/plan service fails, 502/503 when the backend is down or behind a misconfigured proxy.","commonSituations":"VITE_API_BASE_URL unset or wrong in .env so requests hit the Vite dev server instead of the API; CORS rejection surfacing as an opaque network error or a 404 from the dev server; backend not started; reverse proxy (nginx) not forwarding /api to the backend service.","solutions":["Check the status code in the message: 404 = wrong API_BASE or missing route, 422 = payload validation, 500 = backend crash (read backend logs), 502/503 = backend unreachable via proxy.","Verify VITE_API_BASE_URL in frontend/.env(.local) and restart `npm run dev` (Vite only reads env at startup).","Confirm the backend actually exposes POST /api/plan (check the backend router/main file) and that it is listening on the expected port.","Open browser DevTools > Network to inspect the raw /api/plan response body, which this code throws away.","Improve the throw to include the response body for future diagnosis (see exampleFix)."],"exampleFix":"// before\nif (!resp.ok) {\n  throw new Error(`计划模式请求失败: ${resp.status}`);\n}\n\n// after\nif (!resp.ok) {\n  const detail = await resp.text().catch(() => \"\");\n  throw new Error(`计划模式请求失败: ${resp.status} ${detail.slice(0, 200)}`);\n}","handlingStrategy":"try-catch","validationCode":"if (!text || !text.trim()) {\n  throw new Error('规划文本不能为空');\n}\nif (!['TD', 'BU'].includes(direction)) {\n  throw new Error('direction 必须是 TD 或 BU');\n}","typeGuard":"function isPlanDirection(d: string): d is 'TD' | 'BU' {\n  return d === 'TD' || d === 'BU';\n}","tryCatchPattern":"try {\n  const plan = await buildPlan(text, direction);\n} catch (err) {\n  const status = /:(\\s*)(\\d{3})$/.exec(String((err as Error).message))?.[2];\n  if (status === '404') setApiBaseHint();\n  else if (status === '422') showValidationError();\n  else showRetryableError();\n}","preventionTips":["Start the backend before the frontend dev server and verify GET /health (or equivalent) responds.","Keep VITE_API_BASE_URL in .env.development/.env.production and add a startup assertion that it resolves.","Always read the response body before throwing so the server's reason is preserved."],"tags":["http","fetch","api-client","backend-unavailable","env-config"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}