datawhalechina/hello-agents · error
msg
Error message
msg
What it means
In StockSage's StockAnalysis.vue the code throws `new Error(msg)` when the analysis stream request responds non-OK. msg is resolved in priority order: JSON body's `message` field, else raw body text, else statusText — so the literal 'msg' in the error listing is just the variable name; the real message is whatever the server sent. This is the single rejection point for the Buffett-analysis streaming POST.
Source
Thrown at Co-creation-projects/lcyting-StockSage-agent/frontend/src/views/StockAnalysis.vue:1050
headers: {
'Content-Type': 'application/json',
Accept: 'application/x-ndjson',
},
body: JSON.stringify({
stock_code: stockCode.value.trim(),
stock_name: (stockName.value || '').trim(),
}),
})
if (!res.ok) {
const t = await res.text()
let msg = t || res.statusText
try {
const j = JSON.parse(t)
if (j.message) msg = j.message
} catch {
/* ignore */
}
throw new Error(msg)
}
const reader = res.body?.getReader()
if (!reader) throw new Error('无法读取响应流')
const dec = new TextDecoder()
let buf = ''
let streamError = null
let streamFinished = false
while (true) {
const { done: readerDone, value } = await reader.read()
if (value) buf += dec.decode(value, { stream: true })
let nl
while ((nl = buf.indexOf('\n')) >= 0) {
const line = buf.slice(0, nl).trim()
buf = buf.slice(nl + 1)
if (!line) continueView on GitHub (pinned to 606a07d341)
Solutions
- Read the thrown message — when the backend sent {message: ...} it names the exact server-side failure; statusText-only means an empty body (check nginx/gateway).
- Validate stockName is non-empty before invoking the stream (the code trims but the caller may skip checking).
- Confirm the proxy config forwards the analysis endpoint to the backend port in dev and prod.
- Check backend logs when the message references model/API errors (keys, quotas).
Defensive patterns
Strategy: try-catch
Validate before calling
const name = (stockName.value || '').trim();
if (!name) {
ElMessage.warning('请输入股票名称');
return;
} Type guard
function hasErrorMessageFrame(t: string): { message?: string } | null {
try {
const j = JSON.parse(t);
return typeof j === 'object' && j !== null && 'message' in j ? j : null;
} catch {
return null;
}
} Try / catch
try {
await runAnalysisStream(stockName.value.trim());
} catch (err) {
const m = (err as Error).message;
if (/404|Not Found/i.test(m)) hintApiUrl();
else if (/422|validation/i.test(m)) hintStockName();
else showError(m || '分析请求失败');
} Prevention
- Validate the stock name client-side before starting the stream.
- Keep the existing JSON.message-first extraction; also log res.status for diagnosis.
- Verify the dev proxy covers the analysis endpoint before shipping.
When it happens
Trigger: POST to the stock-analysis stream endpoint with {stock_name, ...} returns non-2xx: 404 wrong URL, 422 empty/unknown stock_name (it is trimmed from an input), 500 when the LLM/stream pipeline fails, 502/503 when the gateway is down. The JSON.parse fallback exists because the backend sometimes returns an HTML/plain error page.
Common situations: stockName left blank after trim → backend validation error; backend not running or Vite dev proxy missing for the API path; upstream LLM API key invalid so the handler 500s with {message: ...}; HTML error pages from nginx breaking naive error rendering.
Related errors
- 研究请求失败,状态码:${response.status}
- stream request failed: ${resp.status} ${message}
- 智能体流式请求失败: ${resp.status}
- 研究请求失败,状态码:${response.status}
- 请求失败(${res.status})
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/8f51a18385f60db1.
Report an issue: GitHub.