公司动态

鸿蒙 PC Markdown 编辑器错误处理:让失败可恢复而不是只弹提示

📅 2026/7/19 18:10:38
鸿蒙 PC Markdown 编辑器错误处理:让失败可恢复而不是只弹提示
鸿蒙 PC Markdown 编辑器错误处理让失败可恢复而不是只弹提示编辑器错误处理的第一目标不是把异常文字显示出来而是保证失败后用户仍有下一步。打开失败不能覆盖当前缓冲区保存失败不能清 dirty选择器取消不是错误正则非法不能破坏正文ArkWeb调用失败要保留原生快照恢复记录损坏不能形成启动崩溃循环。本文基于 OhMarkdown梳理状态栏、对话框、回退值、保存恢复和操作互斥组成的可恢复错误模型。代码位于 https://gitcode.com/VON-/codex_md_oh错误先按后果分级可忽略取消用户关闭文件/保存选择器恢复 Ready或 Modified不显示失败。可重试操作目录读取、搜索、导出、打印失败保留当前状态并给状态栏信息。需要决策冲突外部文件变化、Mixed换行、未保存关闭、保存中断使用明确对话框和按钮。数据安全故障短写、旧版本恢复失败、恢复快照写入失败保留缓冲区或备份并标记 P0/P1。按后果分类比把所有 catch弹对话框更适合高频桌面工具。operationStatus 是非阻断反馈页面持有StateprivateoperationStatus:stringReady;StateprivateoperationInProgressfalse;状态栏始终显示 operationStatus并省略超长文本。常见状态包括 Ready、Opened、Modified、Saving、Saved、Loading folder和具体失败。状态文案不能成为业务事实来源。关闭判断读取 dirty保存完成读取 revision不能因为字符串等于 Saved就删除会话。状态栏是输出不是状态机。选择器取消不是异常constopenedDocumentawaitpickMarkdownDocument(context);if(!openedDocument){this.operationStatusthis.hasUnsavedChanges()?Modified:Ready;return;}用户取消是正常分支。保留当前标签、焦点和 dirty不显示红色失败。保存 URI为空和格式对话框取消也使用同样语义。如果保存并关闭来自外层意图finally检查 dirty仍为 true因此不关闭。取消会正确向外传播为“事务未提交”。打开失败不应用半状态this.operationInProgresstrue;this.operationStatusOpening...;try{awaitthis.applyOpenedDocument(awaitreadUtf8Document(documentUri));}catch(error){this.operationStatusOpen failed:${errorinstanceofError?error.message:String(error)};}finally{this.operationInProgressfalse;}读取完整成功后才 apply。文件过大、非法 UTF-8、短读或权限错误都停在旧会话。不要先清编辑器显示 Loading再读否则失败时用户看到空白且误以为内容丢失。页面可以显示进行中状态但正文保持可见。操作互斥阻止失败窗口内切换目标。保存失败保持 dirty保存函数只有完整写入、truncate、fsync且 revision未变化时设置documentDirtyfalse。catch不调用 markSaved也不清恢复草稿。}catch(error){constfailureMessageerrorinstanceofError?error.message:String(error);this.operationStatusSave failed:${failureMessage};}若已创建 pending备份catch先尝试恢复外部旧文件成功显示 previous file restored失败显示 backup retained。无论哪种当前新正文仍在标签中。错误信息告诉用户磁盘结果但不能泄露完整敏感 URI。未来可把底层错误映射为“权限已撤销”“空间不足”“文件被修改”等可操作类别。外部修改是冲突不是普通失败保存前重新读取磁盘与 persisted正文和格式比较。不一致抛出The file changed on disk. Reopen it or use Save As to avoid overwriting external changes.此时不能自动重试因为重试只会重复冲突用户需要 Reopen、Compare或 Save As。当前通过状态栏提示后续应提供操作按钮。冲突处理不应默认“最后写入者获胜”。对话框失败选择保留脏标签关闭对话框 Promise失败.catch((){this.operationStatusUnable to show confirmation;});标签不关闭。Mixed格式对话框失败向上抛保存catch处理dirty保留。只要无法取得明确用户决策就选择不破坏数据。对话框按钮索引之外的返回也视为取消或保留记录不猜用户意图。恢复记录损坏不能阻断启动try{constrecordJSON.parse(awaitfileIo.readText(path,{encoding:utf-8}))asRecoveryRecord;returnisRecoveryRecordValid(record)?record:undefined;}catch(_){returnundefined;}空、过大、非法 JSON和字段错误返回 undefined。应用继续打开。可在非敏感日志记录“恢复记录无效”但不能因为辅助文件损坏形成每次启动崩溃。有效记录显示 Recover/Discard对话框异常时 catch把状态设为 Recovery unavailable记录仍在下一次可重试。恢复队列失败保留最新记录}catch(error){if(this.pendingRecoveryRecordundefined){this.pendingRecoveryRecordrecord;}throwerror;}写入失败时若没有更晚快照把当前记录放回 pending若已有更新版本不用旧记录覆盖。外层状态显示 Recovery failed。不会无限忙重试下一次编辑快照再触发。恢复失败不能阻止用户继续编辑但属于质量红线应在内部试用记录。ArkWeb失败使用旧正文letcontentthis.documentContent;if(this.editorReady){try{constresultawaitthis.editorController.runJavaScript(window.OhMarkdownEditor?.getDocument() ?? );contentthis.decodeJavaScriptString(result);}catch(_){}}捕获失败保留原生最近快照不写空。runEditorScript失败将 editorReadyfalse页面再次 ready后重放文档、模式、主题和同步设置。这种回退可能不是最后一个按键版本所以恢复快照和保存命令仍应尽量在 Web可用时完成。降级路径的目标是“不扩大损失”不是假装没有错误。搜索与正则错误Web收集匹配用 try/catch非法正则返回空数组原生显示 No matches或 Replace failed。当前无法区分语法错误与零匹配是体验边界但正文不会变化。Replace All先收集完整 changes再一次 dispatch。异常发生在 dispatch前不会部分替换单 transaction还可一次撤销。未来应返回结构化错误和表达式位置。导出与打印失败HTML导出先选择 URI再请求 Web字符串、解码、检查非空后写入。任何错误状态为 HTML export failed当前 Markdown会话不变。打印先要求preparePrint() true大文档直接拒绝不创建不完整适配器。导出目标可能已经创建空文件后失败后续应考虑删除或标记不能为了清理目标影响源文档。操作互斥避免竞态错误文件、目录、导出和打印入口检查operationInProgress。finally始终释放。没有 finally会让一次异常永久禁用工作台提前释放又可能让异步返回写错活动会话。当前是全局互斥简单可靠。后续并行后台保存需要显式 OperationContext而不是删除锁。错误后的 UI 要可继续操作按钮 enabled绑定 operationInProgress和 largeDocumentMode。操作结束即恢复状态栏错误不覆盖正文侧边栏仍可切换脏标签仍能另存或复制。阻断对话框只用于需要用户决策的安全边界。下图为真实文档打开后的应用界面。状态栏承担操作结果正文和文件树保持可用。错误截图应使用专用测试文件避免暴露用户路径。行为报告记录失败前后正文哈希和 dirty而不是只截错误文字。错误信息与本地化当前部分状态为英文硬编码资源化尚未完全。做大前应建立错误码到本地化文案和操作的映射底层 Error保留诊断UI显示中文可执行建议。不要把原始系统堆栈直接给用户也不要完全吞掉。开发日志记录错误类别、API和耗时生产 UI显示安全文案。P0 红线覆盖或丢失用户文件、恢复失败且无备份、保存状态错误清 dirty、跨标签写错正文都为 P0应停止扩展。普通搜索失败、预览样式和目录截断可按 P1/P2处理。内部试用每日记录崩溃、数据丢失和 P0/P1不收正文。错误分类必须进入退出评审。当前边界错误仍以字符串为主没有结构化码非法正则与零匹配不区分冲突缺 Compare/Save As快捷动作导出失败目标清理未完善恢复写失败没有指数退避部分文案未本地化。结语可恢复错误处理的判断标准是失败后数据和下一步。OhMarkdown把取消当正常分支读取成功后才应用保存成功后才清 dirty冲突不覆盖记录损坏不阻断启动Bridge失败保留旧正文所有异步用 finally释放互斥。鸿蒙 PC编辑器不可能消除所有故障但可以保证故障不会自动变成数据丢失也不会把用户困在只能重启的界面。