maotoumao/MusicFree · warning
toast.backupFail
Error message
toast.backupFail
What it means
A localized warning toast: "Backup failed: {reason}" (zh: 备份失败). Shown when the WebDAV backup operation's onReject callback fires, i.e. the backup promise was rejected. The raw rejection reason is interpolated into the message and logged to console.
Solutions
- Read the {reason} in the toast / console.log output: it contains the underlying Error message to act on.
- Verify WebDAV settings (webdav.url, webdav.username, webdav.password) in the app's WebDAV Settings before retrying backup.
- Check network connectivity and that the WebDAV server is reachable and accepting writes.
- If reason is an Error, inspect reason.message rather than the object; adjust the caller to normalize `reason?.message ?? reason`.
- Retry the backup after fixing the cause; the failure is recoverable.
Example fix
// before
Toast.warn(t("toast.backupFail", { reason: reason?.message ?? reason }));
// after
const detail = reason instanceof Error ? reason.message : String(reason);
errorLog("备份失败", reason);
Toast.warn(t("toast.backupFail", { reason: detail })); Defensive patterns
Strategy: try-catch
Validate before calling
const url = Config.getConfig("webdav.url");
const username = Config.getConfig("webdav.username");
const password = Config.getConfig("webdav.password");
if (!(url && username && password)) {
Toast.warn(t("toast.resumePreCheckFailed"));
return; // avoid starting a backup that will reject
} Type guard
function hasReason(reason: unknown): reason is { message: string } {
return typeof reason === "object" && reason !== null &&
"message" in reason && typeof (reason as any).message === "string";
} Try / catch
try {
await runBackup();
} catch (reason: any) {
console.log(reason);
Toast.warn(t("toast.backupFail", { reason: reason?.message ?? String(reason) }));
} Prevention
- Validate WebDAV URL/credentials before launching backup.
- Log the full rejection object, not just the toast interpolation, to keep the root cause.
- Distinguish user-facing messages from Error.message when building the toast text.
- Test backup against the real WebDAV server after any credential or URL change.
When it happens
Trigger: Calling the backup action whose dialog provider invokes onReject(reason, hideDialog); the underlying backup routine (e.g. WebDAV upload or storage write) rejects with an Error or string reason, hideDialog() closes the dialog and Toast.warn renders the interpolated failure message.
Common situations: WebDAV server unreachable or wrong URL/credentials during backup; storage permission denied; backup file serialization throws; network timeout mid-upload.
Related errors
- toast.resumePreCheckFailed
- toast.backupFileNotFound
- toast.rememberToSave
- toast.resumeFail
- dialog.markdownDialog.openExternalLink
AI-assisted analysis of maotoumao/MusicFree@d118b18b3d (2026-08-30).
Data as JSON: /api/errors/7d970f3692f1c022.
Report an issue: GitHub.
Appendix: source
Thrown at src/pages/setting/settingTypes/backupSetting.tsx:62
promise: writeInChunks(
`${folder}${folder?.endsWith("/") ? "" : "/"
}backup.json`,
raw,
),
onResolve(_, hideDialog) {
Toast.success(t("toast.backupSuccess"));
hideDialog();
resolve(true);
},
onCancel(hideDialog) {
hideDialog();
resolve(false);
},
onReject(reason, hideDialog) {
hideDialog();
resolve(false);
console.log(reason);
Toast.warn(t("toast.backupFail", { reason: reason?.message ?? reason }));
},
});
});
},
});
};
async function onResumeFromLocal() {
try {
const pickResult = await getDocumentAsync({
copyToCacheDirectory: true,
type: "application/json",
});
if (pickResult.canceled) {
return;
}
const result = await readAsStringAsync(pickResult.assets[0].uri);
return new Promise(resolve => {
View on GitHub (pinned to d118b18b3d)