maotoumao/MusicFree · info

升级失败

Error message

升级失败

What it means

migrate in src/core/musicSheet/migrate.ts moves old music-sheet data from AsyncStorage into the new storage layer and bumps musicSheetVersion to 1; failures are caught and only console.warn('升级失败', e) ("upgrade failed") is emitted — the message is a log, not a thrown error. A swallowed failure leaves sheets unmigrated and the version unbumped.

Source

Thrown at src/core/musicSheet/migrate.ts:30

        // 原来的musicSheets
        const musicSheets: IMusic.IMusicSheetItemBase[] = await oldGetStorage(
            "music-sheets",
        );
        if (!musicSheets) {
            appMeta.setMusicSheetVersion(1);
            return;
        }

        await storage.setSheets(musicSheets);
        await AsyncStorage.removeItem("music-sheets");
        for (let sheet of musicSheets) {
            const musicList = await oldGetStorage(sheet.id);
            await storage.setMusicList(sheet.id, musicList);
            await AsyncStorage.removeItem(sheet.id);
        }
        appMeta.setMusicSheetVersion(1);
    } catch (e) {
        console.warn("升级失败", e);
    }
}

export const migrateV2 = {
    migrate(sheetId: string, musicItems: IMusic.IMusicItem[]) {
        const dbUpdated = appMeta.musicSheetVersion === 2;
        if (dbUpdated) {
            return;
        }
        let dirty = false;
        const now = Date.now();
        musicItems.forEach((it, index) => {
            if (!it.$timestamp || it.$sortIndex === undefined) {
                it.$timestamp = now;
                it.$sortIndex = index;
                dirty = true;
            }
        });

View on GitHub (pinned to d118b18b3d)

Solutions

  1. Reproduce with console output: the warn includes the original error — fix the underlying storage failure it names.
  2. Because appMeta.setMusicSheetVersion(1) only runs on success, relaunching the app re-attempts migration once the storage issue is fixed.
  3. If a specific sheet is corrupt, wrap per-sheet migration in its own try/catch so one bad sheet doesn't stop the rest.
  4. Back up AsyncStorage data before upgrading if sheets are valuable.

Example fix

// before
} catch (e) {
  console.warn("升级失败", e);
}
// after
} catch (e) {
  console.warn("升级失败", e);
  Toast.warn(t("toast.migrateFail", { reason: e?.message ?? e }));
}
Defensive patterns

Strategy: retry

Validate before calling

const raw = await AsyncStorage.getItem(sheet.id);
if (!raw) { appMeta.setMusicSheetVersion(1); return; } // nothing to migrate
JSON.parse(raw); // fail fast on corrupt data before touching new storage

Try / catch

try {
  await migrateSheets();
} catch (e) {
  console.warn('升级失败', e);
  // version not bumped -> next launch retries automatically
}

Prevention

When it happens

Trigger: Running the app after an upgrade where AsyncStorage.getItem for a sheet id fails, storage.setMusicList rejects (DB locked/corrupt), or AsyncStorage.removeItem fails — any rejection in the per-sheet loop triggers the catch.

Common situations: Upgrading from a very old version with large sheets (quota/serialization issues); corrupted AsyncStorage after a failed update; concurrent migration attempts; app killed mid-migration leaving partial state.

Related errors


AI-assisted analysis of maotoumao/MusicFree@d118b18b3d (2026-08-30). Data as JSON: /api/errors/8cca0254ebf44873. Report an issue: GitHub.