datawhalechina/hello-agents · error · Error
生成失败
Error message
生成失败
What it means
'生成失败' (generation failed) is the default message assigned in StockAnalysis.vue's stream loop when an NDJSON frame arrives with type:'error' but carries neither message nor content fields. The frame signals a server-side error mid-stream; the thrown Error surfaces it after the read loop exits. It only shows the literal '生成失败' when the server sent a bare error event with no detail.
Source
Thrown at Co-creation-projects/lcyting-StockSage-agent/frontend/src/views/StockAnalysis.vue:1085
buf = buf.slice(nl + 1)
if (!line) continue
let obj
try {
obj = JSON.parse(line)
} catch {
continue
}
const deltaPiece = obj.text ?? obj.content
if (obj.type === 'delta' && deltaPiece) {
buffettStreamRaw.value += deltaPiece
} else if (obj.type === 'error') {
streamError = obj.message || obj.content || '生成失败'
} else if (obj.type === 'done') {
streamFinished = true
}
}
if (streamError) throw new Error(streamError)
if (streamFinished || readerDone) break
}
const tail = buf.trim()
if (tail) {
try {
const obj = JSON.parse(tail)
if (obj.type === 'error') throw new Error(obj.message || obj.content || '生成失败')
const tailDelta = obj.text ?? obj.content
if (obj.type === 'delta' && tailDelta) buffettStreamRaw.value += tailDelta
} catch (e) {
if (!(e instanceof SyntaxError)) throw e
}
}
const md = buffettStreamRaw.value.trim()
buffettAiMarkdown.value = md
buffettStreamRaw.value = ''View on GitHub (pinned to 606a07d341)
Solutions
- Check the backend's error-frame emitter — make it always include the exception message so this default never fires blind.
- Read backend logs at the timestamp of the failed stream for the real exception.
- If it's provider rate-limiting/quota, fix keys/limits upstream and retry the analysis.
- For timeout-class failures, chunk the analysis request or increase server-side LLM timeouts.
Defensive patterns
Strategy: try-catch
Type guard
function isErrorFrame(obj: unknown): obj is { type: 'error'; message?: string; content?: string } {
return typeof obj === 'object' && obj !== null && (obj as { type?: unknown }).type === 'error';
} Try / catch
try {
await streamBuffettAnalysis();
} catch (err) {
const m = (err as Error).message;
if (m === '生成失败') {
// bare error frame — check server logs; likely LLM provider fault
showError('生成失败:上游模型异常,请稍后重试');
} else {
showError(m);
}
} Prevention
- Make the backend always attach message/content to error frames so the default text never fires blind.
- Keep partial deltas rendered (buffettStreamRaw already accumulates) so users keep what arrived before the error.
- Retry once on transient provider errors before surfacing the failure.
When it happens
Trigger: The analysis stream opens OK, deltas flow, then the server emits {type:'error'} (optionally with message/content) — LLM provider failure mid-generation, upstream timeout, token limit hit, or internal exception in the analysis pipeline. The default text appears specifically when the error frame is empty.
Common situations: LLM API rate-limit/key errors surfacing mid-stream; long analyses hitting provider timeouts; backend catching an exception and emitting a bare error frame without details.
Related errors
- msg
- 无法读取响应流
- 研究请求失败,状态码:${response.status}
- stream request failed: ${resp.status} ${message}
- 智能体流式请求失败: ${resp.status}
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/e3440af8552bb448.
Report an issue: GitHub.