{"record":{"id":"ee5f557e0d1093d1","repo":"maotoumao/MusicFree","slug":"toast-resumefail","errorCode":null,"errorMessage":"toast.resumeFail","messagePattern":"toast\\.resumeFail","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/pages/setting/settingTypes/backupSetting.tsx","lineNumber":107,"sourceCode":"                        Toast.success(t(\"toast.resumeSuccess\"));\r\n                        hideDialog();\r\n                        resolve(true);\r\n                    },\r\n                    onCancel(hideDialog) {\r\n                        hideDialog();\r\n                        resolve(false);\r\n                    },\r\n                    onReject(reason, hideDialog) {\r\n                        hideDialog();\r\n                        resolve(false);\r\n                        console.log(reason);\r\n                        Toast.warn(t(\"toast.resumeFail\", { reason: reason?.message ?? reason }));\r\n                    },\r\n                });\r\n            });\r\n        } catch (e: any) {\r\n            errorLog(\"恢复失败\", e);\r\n            Toast.warn(t(\"toast.resumeFail\", { reason: e?.message ?? e }));\r\n        }\r\n    }\r\n\r\n    async function onResumeFromUrl() {\r\n        showPanel(\"SimpleInput\", {\r\n            title: t(\"backupAndResume.resumeFromUrlDialogTitle\"),\r\n            placeholder: t(\"backupAndResume.resumeFromUrlDialogPlaceHolder\"),\r\n            maxLength: 1024,\r\n            async onOk(text, closePanel) {\r\n                try {\r\n                    const url = text.trim();\r\n                    if (url.endsWith(\".json\") || url.endsWith(\".txt\")) {\r\n                        const raw = (await axios.get(text)).data;\r\n                        await Backup.resume(raw, resumeMode);\r\n                        Toast.success(t(\"toast.resumeSuccess\"));\r\n                        closePanel();\r\n                    } else {\r\n                        throw \"无效的URL\";\r","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/backupSetting.tsx#L89-L125","documentation":"onResumeFromLocal in backupSetting.tsx restores a local backup; failures inside the restore callback and the outer try/catch both surface as Toast.warn(t('toast.resumeFail', {reason})). 'toast.resumeFail' is the i18n key for \"restore failed\", carrying the underlying exception message as reason.","triggerScenarios":"Restoring from a local backup file when: the backup JSON is corrupt or from an incompatible app version, file read fails (permission/moved file), or the import routine throws inside its callback or the awaited restore call throws.","commonSituations":"Selecting an old/edited backup file whose schema no longer matches; restoring a backup made on a newer app version; file picker returning a path the native layer cannot read; partial/corrupted file from an interrupted export.","solutions":["Read the logged '恢复失败' (restore failed) error to see the exact cause (parse error vs IO error vs schema mismatch).","Re-export a fresh backup and retry the restore.","Validate the backup JSON structure before importing (check version fields and required keys).","Upgrade the app if the backup was produced by a newer version, or add the toast.resumeFail key to locales so the reason is visible."],"exampleFix":"// before\nawait resumeFromLocal(file);\n// after\ntry {\n  const raw = JSON.parse(fileContent);\n  if (!raw || typeof raw !== 'object') throw new Error('invalid backup file');\n  await resumeFromLocal(raw);\n} catch (e) {\n  Toast.warn(t('toast.resumeFail', { reason: e?.message ?? e }));\n}","handlingStrategy":"try-catch","validationCode":"const backup = JSON.parse(fileContent); // throws early on corrupt file\nif (!backup || typeof backup !== 'object' || !Array.isArray(backup.musicShows)) {\n  throw new Error('backup schema mismatch');\n}","typeGuard":"function isValidBackup(b: unknown): b is BackupShape {\n  return !!b && typeof b === 'object' && 'version' in (b as object);\n}","tryCatchPattern":"try {\n  await resumeFromLocal(file);\n} catch (e) {\n  errorLog('恢复失败', e);\n  Toast.warn(t('toast.resumeFail', { reason: e?.message ?? e }));\n}","preventionTips":["Validate backup JSON version/shape before importing.","Refuse backups from newer app versions with a clear message.","Verify file readability right after picking it, before starting restore.","Add toast.resumeFail to all locale bundles so users see the real reason."],"tags":["backup","restore","i18n","file-io","data-integrity"],"backgroundTag":"backup-restore-failed","analyzedSha":"d118b18b3d0c904400f7eea7bf99c0ceec6c1aee","analyzedAt":"2026-08-30T11:49:12.932Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}