'How to abandon a manual Room migration script, and fall back to destructive migration?

In the app I'm working on, we had a complex manual migration that required data parsing, manual SQL commands, etc. This was to convert a List<X> column into a new linked table of X. I've previously written about the approach, but the specific commands are not especially relevant for this question.

The issue I'm encountering is ~1% of users are experiencing a crash as part of this migration. This cannot be reproduced in testing, and due to our table's size, Crashlytics cannot show any useful error:

crashlytics truncated error

Losing customer data isn't catastrophic in this context, but being stuck in the current "try migrate, crash, reopen app and repeat" loop is. As such, I want to just give up on the migration and fall back to a destructive migration if we encounter an exception.

Any ideas how this can be done? My current solution is rerunning the DB changes (but not the presumably failing data migration) inside the catch, but this feels very hacky.


Our database is defined as:

Room.databaseBuilder(
        context.applicationContext,
        CreationDatabase::class.java,
        "creation_database"
    )
    .addMigrations(MIGRATION_11_12, MIGRATION_14_15)
    .fallbackToDestructiveMigration()
    .build()

where MIGRATION_14_15 is:

private val MIGRATION_14_15 = object : Migration(14, 15) {
    override fun migrate(database: SupportSQLiteDatabase) {
        try {
            // database.execSQL create table etc
        } catch (e: Exception) {
            e.printStackTrace()
            // Here is where I want to give up, and start the DB from scratch
        }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source