Crash on startup if an unrecoverable error happens (#2019)

* Crash on startup if an unrecoverable error happens

* Changelog
This commit is contained in:
Mitchell Syer
2026-05-14 11:44:52 -04:00
committed by GitHub
parent 740db4f1ab
commit 82df985201
6 changed files with 43 additions and 27 deletions

View File

@@ -67,7 +67,7 @@ jobs:
export LD_PRELOAD="$(pwd)/scripts/resources/catch_abort.so" export LD_PRELOAD="$(pwd)/scripts/resources/catch_abort.so"
JAR=$(ls ./server/build/*.jar| head -1) JAR=$(ls ./server/build/*.jar| head -1)
set +e set +e
timeout 30s java -DcrashOnFailedMigration=true \ timeout 30s java \
-Dsuwayomi.tachidesk.config.server.systemTrayEnabled=false \ -Dsuwayomi.tachidesk.config.server.systemTrayEnabled=false \
-Dsuwayomi.tachidesk.config.server.initialOpenInBrowserEnabled=false \ -Dsuwayomi.tachidesk.config.server.initialOpenInBrowserEnabled=false \
-Dsuwayomi.tachidesk.config.server.databaseType=POSTGRESQL \ -Dsuwayomi.tachidesk.config.server.databaseType=POSTGRESQL \
@@ -83,7 +83,7 @@ jobs:
exit "$ecode" exit "$ecode"
fi fi
timeout 30s java -DcrashOnFailedMigration=true \ timeout 30s java \
-Dsuwayomi.tachidesk.config.server.systemTrayEnabled=false \ -Dsuwayomi.tachidesk.config.server.systemTrayEnabled=false \
-Dsuwayomi.tachidesk.config.server.initialOpenInBrowserEnabled=false \ -Dsuwayomi.tachidesk.config.server.initialOpenInBrowserEnabled=false \
-jar "$JAR" -jar "$JAR"

View File

@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Changed ### Changed
- (Database/H2) Use the latest H2 database engine - (Database/H2) Use the latest H2 database engine
- (Startup) Crash on startup if an unrecoverable error happens
### Fixed ### Fixed
- (CloudFlareInterceptor) Don't send the `cf_clearance` cookie back to Flaresolverr - (CloudFlareInterceptor) Don't send the `cf_clearance` cookie back to Flaresolverr

View File

@@ -5,6 +5,8 @@ import android.content.Context
import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.KotlinLogging
import suwayomi.tachidesk.manga.impl.update.IUpdater import suwayomi.tachidesk.manga.impl.update.IUpdater
import suwayomi.tachidesk.server.database.H2Migration import suwayomi.tachidesk.server.database.H2Migration
import suwayomi.tachidesk.server.util.ExitCode
import suwayomi.tachidesk.server.util.shutdownApp
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@@ -99,31 +101,35 @@ private val MIGRATIONS =
fun runMigrations(applicationDirs: ApplicationDirs) { fun runMigrations(applicationDirs: ApplicationDirs) {
val logger = KotlinLogging.logger("Migration") val logger = KotlinLogging.logger("Migration")
try {
val migrationPreferences =
Injekt
.get<Application>()
.getSharedPreferences(
"migrations",
Context.MODE_PRIVATE,
)
val version = migrationPreferences.getInt("version", 0)
val migrationPreferences = logger.info { "Running migrations, previous version $version, target version ${MIGRATIONS.size}" }
Injekt
.get<Application>()
.getSharedPreferences(
"migrations",
Context.MODE_PRIVATE,
)
val version = migrationPreferences.getInt("version", 0)
logger.info { "Running migrations, previous version $version, target version ${MIGRATIONS.size}" } MIGRATIONS.forEachIndexed { index, (migrationName, migrationFunction) ->
val migrationVersion = index + 1
MIGRATIONS.forEachIndexed { index, (migrationName, migrationFunction) -> val isMigrationRequired = version < migrationVersion
val migrationVersion = index + 1 if (!isMigrationRequired) {
logger.info { "Skipping migration version $migrationVersion: $migrationName" }
return@forEachIndexed
}
val isMigrationRequired = version < migrationVersion logger.info { "Running migration version $migrationVersion: $migrationName" }
if (!isMigrationRequired) {
logger.info { "Skipping migration version $migrationVersion: $migrationName" } migrationFunction(applicationDirs)
return@forEachIndexed
migrationPreferences.edit().putInt("version", migrationVersion).apply()
} }
} catch (e: Exception) {
logger.info { "Running migration version $migrationVersion: $migrationName" } logger.error(e) { "Failed to run migrations" }
shutdownApp(ExitCode.MigrationsRunFailure)
migrationFunction(applicationDirs)
migrationPreferences.edit().putInt("version", migrationVersion).apply()
} }
} }

View File

@@ -366,6 +366,7 @@ fun applicationSetup() {
} }
} catch (e: Exception) { } catch (e: Exception) {
logger.error(e) { "Exception while creating initial server.conf" } logger.error(e) { "Exception while creating initial server.conf" }
shutdownApp(ExitCode.SetupConfFileFailed)
} }
// copy local source icon // copy local source icon
@@ -378,6 +379,7 @@ fun applicationSetup() {
} }
} catch (e: Exception) { } catch (e: Exception) {
logger.error(e) { "Exception while copying Local source's icon" } logger.error(e) { "Exception while copying Local source's icon" }
shutdownApp(ExitCode.LocalSourceIconCopyFailure)
} }
// fixes #119 , ref: // fixes #119 , ref:
@@ -395,7 +397,12 @@ fun applicationSetup() {
databaseUp() databaseUp()
LocalSource.register() try {
LocalSource.register()
} catch (e: Exception) {
logger.error(e) { "Failed to setup LocalSource" }
shutdownApp(ExitCode.LocalSourceSetupFailure)
}
serverConfig.subscribeTo( serverConfig.subscribeTo(
combine<Any, DatabaseSettings>( combine<Any, DatabaseSettings>(

View File

@@ -185,8 +185,6 @@ fun databaseUp() {
runMigrations(migrations) runMigrations(migrations)
} catch (e: Exception) { } catch (e: Exception) {
logger.error(e) { "Error up-to-database migration" } logger.error(e) { "Error up-to-database migration" }
if (System.getProperty("crashOnFailedMigration").toBoolean()) { shutdownApp(ExitCode.DbMigrationFailure)
shutdownApp(ExitCode.DbMigrationFailure)
}
} }
} }

View File

@@ -21,6 +21,10 @@ enum class ExitCode(
WebUISetupFailure(3), WebUISetupFailure(3),
ConfigMigrationMisconfiguredFailure(4), ConfigMigrationMisconfiguredFailure(4),
DbMigrationFailure(5), DbMigrationFailure(5),
SetupConfFileFailed(6),
LocalSourceIconCopyFailure(7),
LocalSourceSetupFailure(8),
MigrationsRunFailure(9),
} }
fun shutdownApp(exitCode: ExitCode) { fun shutdownApp(exitCode: ExitCode) {