From 1fc337d9b8c9ee869625758e371a08bd358a1491 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Sun, 15 Dec 2024 13:50:36 +0100 Subject: [PATCH] Make engine more resilient against init crashes --- .../de/staropensource/engine/base/Engine.kt | 44 ++++++++++++------- .../EngineInitializationFailureException.kt | 32 ++++++++++++++ 2 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 base/src/main/kotlin/de/staropensource/engine/base/exception/EngineInitializationFailureException.kt diff --git a/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt b/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt index 4ae9368..57226c3 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt @@ -20,6 +20,7 @@ package de.staropensource.engine.base +import de.staropensource.engine.base.exception.EngineInitializationFailureException import de.staropensource.engine.base.utility.Environment import de.staropensource.engine.base.utility.FileAccess import de.staropensource.engine.logging.Logger @@ -78,31 +79,38 @@ class Engine private constructor() { * and generally performs actions which * should only be executed once. * + * @return `true` if bootstrapping was performed successfully, `false` if failed * @throws Throwable on initialization error * @since v1-alpha10 */ @JvmStatic @Throws(Throwable::class) - private fun bootstrap() { + private fun bootstrap(): Boolean { if (state != State.UNINITIALIZED || bootstrapping != null) - return + return true - bootstrapping = true - logger.info("Bootstrapping") + try { + bootstrapping = true + logger.info("Bootstrapping") - // Run bootstrapping code + // Run bootstrapping code - bootstrapping = false + bootstrapping = false + return true + } catch (exception: Exception) { + logger.crash("Engine failed to bootstrap", throwable = exception, fatal = true) + return false + } } /** * Initializes the engine. * - * @throws Throwable on initialization error + * @throws EngineInitializationFailureException on initialization error * @since v1-alpha10 */ @JvmStatic - @Throws(Throwable::class) + @Throws(EngineInitializationFailureException::class) fun initialize() { // Abort if initializing, shutting down // or the engine has crashed @@ -114,16 +122,22 @@ class Engine private constructor() { ) return // Bootstrap if not already done so - bootstrap() + if (!bootstrap()) + return - state = State.INITIALIZING - logger.info("Initializing") + try { + state = State.INITIALIZING + logger.info("Initializing") - // Run initialization code - Environment.detect() - FileAccess.updateDefaultPaths() + // Run initialization code + Environment.detect() + FileAccess.updateDefaultPaths() - state = State.INITIALIZED + state = State.INITIALIZED + } catch (exception: Exception) { + logger.crash("Engine failed to initialize", throwable = exception, fatal = true) + throw EngineInitializationFailureException(exception) + } } /** diff --git a/base/src/main/kotlin/de/staropensource/engine/base/exception/EngineInitializationFailureException.kt b/base/src/main/kotlin/de/staropensource/engine/base/exception/EngineInitializationFailureException.kt new file mode 100644 index 0000000..fe08ab8 --- /dev/null +++ b/base/src/main/kotlin/de/staropensource/engine/base/exception/EngineInitializationFailureException.kt @@ -0,0 +1,32 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Authors + * Licensed under the GNU Affero General Public License v3 + * with an exception allowing classpath linking. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.staropensource.engine.base.exception + +/** + * Thrown when the engine fails to + * initialize or bootstrap itself. + * + * After this occurs, it will no longer + * be possible to initialize the engine. + * + * @since v1-alpha10 + */ +class EngineInitializationFailureException(val throwable: Throwable) : RuntimeException("The StarOpenSource Engine failed to initialize", throwable)