{"record":{"id":"a3e3f8e55aa3d63c","repo":"maotoumao/MusicFree","slug":"toast-resumeprecheckfailed","errorCode":null,"errorMessage":"toast.resumePreCheckFailed","messagePattern":"toast\\.resumePreCheckFailed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/pages/setting/settingTypes/backupSetting.tsx","lineNumber":140,"sourceCode":"                        Toast.success(t(\"toast.resumeSuccess\"));\r\n                        closePanel();\r\n                    } else {\r\n                        throw \"无效的URL\";\r\n                    }\r\n                } catch (e: any) {\r\n                    Toast.warn(t(\"toast.resumeFail\", { reason: e?.message ?? e }));\r\n                }\r\n            },\r\n        });\r\n    }\r\n\r\n    async function onResumeFromWebdav() {\r\n        const url = Config.getConfig(\"webdav.url\");\r\n        const username = Config.getConfig(\"webdav.username\");\r\n        const password = Config.getConfig(\"webdav.password\");\r\n\r\n        if (!(username && password && url)) {\r\n            Toast.warn(t(\"toast.resumePreCheckFailed\"));\r\n            return;\r\n        }\r\n        const client = createClient(url, {\r\n            authType: AuthType.Password,\r\n            username: username,\r\n            password: password,\r\n        });\r\n\r\n        if (!(await client.exists(\"/MusicFree/MusicFreeBackup.json\"))) {\r\n            Toast.warn(t(\"toast.backupFileNotFound\"));\r\n            return;\r\n        }\r\n\r\n        try {\r\n            const resumeData = await client.getFileContents(\r\n                \"/MusicFree/MusicFreeBackup.json\",\r\n                {\r\n                    format: \"text\",\r","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/backupSetting.tsx#L122-L158","documentation":"A localized warning toast: \"Please configure in「Webdav Settings」first, then restore\" (zh: 恢复前检查失败). Shown by onResumeFromWebdav when its pre-check fails: any of the WebDAV config values (webdav.url, webdav.username, webdav.password) is missing, so the function returns early without creating the WebDAV client.","triggerScenarios":"User taps restore-from-WebDAV while Config.getConfig(\"webdav.url\"), getConfig(\"webdav.username\") or getConfig(\"webdav.password\") is falsy; the guard `if (!(username && password && url))` triggers the toast and returns before createClient is called.","commonSituations":"Fresh install where WebDAV was never configured; user cleared settings or the config keys were renamed/migrated between app versions; password field left empty; user tries restore before backup setup.","solutions":["Open WebDAV Settings in the backup/restore page and fill in the server URL, username, and password, then retry restore.","Verify the config keys exist: Config.getConfig(\"webdav.url\"), \"webdav.username\", \"webdav.password\" return non-empty values.","If settings appear filled but the toast still fires, check for whitespace-only values that are truthy-safe but broken, or a config storage reset after an app update.","Re-enter credentials if a version migration changed the webdav.* config keys."],"exampleFix":"// before\nif (!(username && password && url)) {\n    Toast.warn(t(\"toast.resumePreCheckFailed\"));\n    return;\n}\n// after\nif (!(username && password && url)) {\n    Toast.warn(t(\"toast.resumePreCheckFailed\"));\n    navigation.navigate(\"webdavSettings\"); // guide user to fix config\n    return;\n}","handlingStrategy":"validation","validationCode":"const url = Config.getConfig(\"webdav.url\");\nconst username = Config.getConfig(\"webdav.username\");\nconst password = Config.getConfig(\"webdav.password\");\nconst webdavConfigured =\n    typeof url === \"string\" && url.trim().length > 0 &&\n    typeof username === \"string\" && username.trim().length > 0 &&\n    typeof password === \"string\" && password.length > 0;\nif (!webdavConfigured) {\n    Toast.warn(t(\"toast.resumePreCheckFailed\"));\n    return;\n}","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n    return typeof v === \"string\" && v.trim().length > 0;\n}","tryCatchPattern":"if (!(isNonEmptyString(url) && isNonEmptyString(username) && isNonEmptyString(password))) {\n    Toast.warn(t(\"toast.resumePreCheckFailed\"));\n    return;\n}\ntry {\n    const client = createClient(url, { authType: AuthType.Password, username, password });\n} catch (e: any) {\n    Toast.warn(t(\"toast.resumeFail\", { reason: e?.message ?? String(e) }));\n}","preventionTips":["Complete WebDAV Settings (URL, username, password) before attempting any WebDAV backup/restore.","Show the config screen directly when the pre-check fails instead of only warning.","Trim string config values and check length, not just truthiness, to catch whitespace-only entries.","After app updates, verify webdav.* config keys still resolve via Config.getConfig."],"tags":["i18n","webdav","precondition-failed","configuration","ui-toast"],"backgroundTag":"missing-webdav-config","analyzedSha":"d118b18b3d0c904400f7eea7bf99c0ceec6c1aee","analyzedAt":"2026-08-30T11:49:12.932Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}