Silent Data Loss & Broken Error Contract in Saver.save()
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- api
Research direction
Start by reading the save() implementations in src/components/modules/saver.ts and src/components/modules/api/saver.ts, focusing on how errors are handled and propagated. Verify that failures during block saving or sanitization reject the public save() Promise rather than resolving with undefined, while read-only behavior remains unchanged.
Written by the indexing model from the issue text.
Description
2. Silent Data Loss & Broken Error Contract in Saver.save()
📍 Affected Locations
src/components/modules/saver.ts(Lines 34–48)src/components/modules/api/saver.ts(Lines 27–38)
🔍 Deep Technical Diagnosis
In src/components/modules/saver.ts:
// src/components/modules/saver.ts: Lines 34-48
public async save(): Promise<OutputData> {
const { BlockManager, Tools } = this.Editor;
const blocks = BlockManager.blocks,
chainData = [];
try {
blocks.forEach((block: Block) => {
chainData.push(this.getSavedData(block));
});
const extractedData = await Promise.all(chainData) as Array<Pick<SavedData, 'data' | 'tool'>>;
const sanitizedData = await sanitizeBlocks(extractedData, (name) => {
return Tools.blockTools.get(name).sanitizeConfig;
});
return this.makeOutput(sanitizedData);
} catch (e) {
_.logLabeled(`Saving failed due to the Error %o`, 'error', e);
// BUG: No return statement, no rethrow, no Promise.reject!
// Silently completes and returns `undefined`!
}
}
And in the public API exposed to developers (src/components/modules/api/saver.ts):
// src/components/modules/api/saver.ts: Lines 27-37
public save(): Promise<OutputData> {
const errorText = 'Editor\'s content can not be saved in read-only mode';
if (this.Editor.ReadOnly.isEnabled) {
_.logLabeled(errorText, 'warn');
return Promise.reject(new Error(errorText));
}
return this.Editor.Saver.save();
}
💥 Real-World Impact (Catastrophic Data Loss)
When an exception occurs during block saving or sanitization (for instance, a custom tool throws in its save() method, or a circular JSON structure is encountered):
Saver.save()swallows the exception and returnsundefined.- The
editor.save()Promise resolves toundefinedinstead of rejecting. - Typical application backend code looks like:
try { const output = await editor.save(); // If saving fails, the developer expects `catch` to trigger! // Instead, output is `undefined`! await api.saveArticle({ id: articleId, content: output }); } catch (error) { toast.error("Saving failed!"); } - The database receives
{ content: undefined }(or null) and overwrites the existing document, wiping out all previously saved user content! - Violates Promise conventions and the TypeScript contract declaring
save(): Promise<OutputData>.
💡 Proposed Solution & Patch
src/components/modules/saver.ts
@@ -44,6 +44,7 @@ export default class Saver extends Module {
return this.makeOutput(sanitizedData);
} catch (e) {
_.logLabeled(`Saving failed due to the Error %o`, 'error', e);
+ throw e;
}
}
- Dominant language
- TypeScript
- Stars
- 32k
- Forks
- 2.2k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 2
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from codex-team/editor.js
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
codex-team/editor.js#3032 · 1 comment ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
codex-team/editor.js#3029 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
codex-team/editor.js#3005 · 1 comment ·
-
good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
codex-team/editor.js#2616 · 1 comment · 1 reaction ·
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 72/100
codex-team/editor.js#3031 ·
All issues in codex-team/editor.js
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
copse-dev/agent-pane#2953 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·