datawhalechina/hello-agents · error · Error
更新失败:
Error message
更新失败:
What it means
'更新失败: ' + e (update failed) is alerted by the NovelGenerator frontend when PUT {API_URL}/chapter/update responds non-OK; the thrown Error wraps the response body text. The request updates an existing chapter {novel_id, title, note_id, content, chapter_title}; note_id is chapter.id from the local list, so stale ids after backend state loss are the dominant cause.
Source
Thrown at Co-creation-projects/lgs-only-NovelGenerator/frontend/index.html:542
}
};
const updateChapter = async (chapter) => {
loading.value = true;
currentAction.value = 'update_chapter_' + chapter.id;
try {
const res = await fetch(`${API_URL}/chapter/update`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
novel_id: project.novel_id,
title: project.title,
note_id: chapter.id,
content: chapter.content,
chapter_title: chapter.title // 支持修改标题
})
});
if (!res.ok) throw new Error(await res.text());
alert('章节更新成功');
} catch (e) {
alert('更新失败: ' + e);
} finally {
loading.value = false;
currentAction.value = null;
}
};
const deleteChapter = async (chapter) => {
if(!confirm('确定要删除这一章吗?')) return;
loading.value = true;
currentAction.value = 'delete_chapter_' + chapter.id;
try {
const params = new URLSearchParams({
novel_id: project.novel_id,
title: project.title,
note_id: chapter.idView on GitHub (pinned to 606a07d341)
Solutions
- Guard: only enable chapter editing when chapter.id is truthy.
- Read the alert body — it distinguishes not-found from validation errors.
- Require chapter_title and content non-empty before the PUT.
- On 404, refresh the chapter list from the server to resync ids.
Example fix
// before
const updateChapter = async (chapter) => { /* no guard */ }
// after
const updateChapter = async (chapter) => {
if (!chapter.id) { alert('该章节尚未生成,无法更新'); return; }
if (!chapter.title?.trim() || !chapter.content?.trim()) { alert('标题和内容不能为空'); return; }
// ... existing fetch
} Defensive patterns
Strategy: validation
Validate before calling
if (!chapter.id) { alert('该章节尚未生成,无法更新'); return; }
if (!chapter.title?.trim() || !chapter.content?.trim()) { alert('章节标题和内容不能为空'); return; } Type guard
function isChapterUpdatePayload(p: unknown): p is { novel_id: string; title: string; note_id: string; content: string; chapter_title: string } {
return typeof p === 'object' && p !== null
&& typeof (p as { note_id?: unknown }).note_id === 'string'
&& typeof (p as { chapter_title?: unknown }).chapter_title === 'string';
} Try / catch
try {
const res = await fetch(`${API_URL}/chapter/update`, opts);
if (!res.ok) throw new Error(`${res.status}: ${(await res.text()).slice(0, 200)}`);
alert('章节更新成功');
} catch (e) {
const m = e instanceof Error ? e.message : String(e);
if (m.startsWith('404')) refreshChapterList(); // resync stale ids
else alert('更新失败: ' + m);
} Prevention
- Gate edit/save UI on chapter.id being present.
- On 404, refetch the chapter list to resynchronize ids after backend state loss.
- Require non-empty title and content client-side before the PUT.
When it happens
Trigger: PUT /chapter/update returns 404 (chapter.id unknown — backend restarted, chapter deleted, or id from a failed generate), 422 (chapter_title/content missing or empty because the edit wasn't saved), 500 storage failure. Editing a chapter whose generation never completed (id never assigned) also produces doomed requests.
Common situations: Editing right after a backend restart wiped in-memory chapters; chapter_title left blank; saving an edit on a chapter that failed to generate (no valid id).
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/bcacbd78b9fa8b77.
Report an issue: GitHub.