Add soft-crash functionality

This commit is contained in:
JeremyStar™ 2024-07-11 05:43:42 +02:00
parent 7d8d277bc1
commit 97d1c391bf
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
5 changed files with 94 additions and 13 deletions

View file

@ -60,7 +60,7 @@ public final class JvmInformation {
try {
return Integer.parseInt(version);
} catch (NumberFormatException exception) {
Logger.crash(new LogIssuer(JvmInformation.class, CodePart.ENGINE), "Could not parse Java version: Integer conversion failed for string \"" + version + "\"", exception);
Logger.crash(new LogIssuer(JvmInformation.class, CodePart.ENGINE), "Could not parse Java version: Integer conversion failed for string \"" + version + "\"", exception, true);
throw exception;
}
}

View file

@ -0,0 +1,43 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Contributors
* Licensed under the GNU Affero General Public License v3
*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.events;
import de.staropensource.sosengine.base.classes.events.Event;
import de.staropensource.sosengine.base.classes.helpers.EventHelper;
/**
* Called in the event of a soft engine crash
* ie. a crash which was declared as handled.
*
* @since 1-alpha0
*/
@SuppressWarnings({ "unused" })
public final class EngineSoftCrashEvent implements Event {
/**
* Constructs this class.
*/
public EngineSoftCrashEvent() {}
/** {@inheritDoc} */
@Override
public void callEvent() {
EventHelper.invokeAnnotatedMethods(getClass());
}
}

View file

@ -25,6 +25,7 @@ import de.staropensource.sosengine.base.classes.Placeholder;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.classes.logging.LogLevel;
import de.staropensource.sosengine.base.events.EngineCrashEvent;
import de.staropensource.sosengine.base.events.EngineSoftCrashEvent;
import de.staropensource.sosengine.base.internal.placeholders.crashhandler.*;
import de.staropensource.sosengine.base.utility.PlaceholderEngine;
import lombok.Getter;
@ -69,6 +70,7 @@ public final class CrashHandler {
@Setter
private static String crashTemplate = """
<fg:red><bold>
%handled%
------------------------
sos!engine crash
------------------------
@ -76,7 +78,8 @@ public final class CrashHandler {
------------------------
sos!engine crash
------------------------<reset>
------------------------
%handled%<reset>
""";
/**
@ -109,11 +112,16 @@ public final class CrashHandler {
* @param throwable simply to provide stacktrace and further insight into the crash, can be set to {@code null}
* @since 1-alpha0
*/
public static synchronized void handleCrash(@NotNull LogIssuer logIssuer, @NotNull String message, @Nullable Throwable throwable) {
public static synchronized void handleCrash(@NotNull LogIssuer logIssuer, @NotNull String message, @Nullable Throwable throwable, boolean throwableHandled) {
if (throwable == null)
throwableHandled = false;
String base = crashTemplate;
// Replace '%content%' with crash content
base = base.replace("%content%", processCrashContent()); // This is so simple we don't need the PlaceholderEngine to do it for us
// This is so simple we don't need the PlaceholderEngine to do it for us
base = base
.replace("%content%", processCrashContent())
.replace("%handled%", throwableHandled ? "!!! This throwable is declared as handled and has been passed down the execution chain !!!" : "");
// Invoke LoggerImpl#prePlaceholder
base = Logger.getLoggerImplementation().prePlaceholder(LogLevel.CRASH, logIssuer, base);
@ -140,14 +148,18 @@ public final class CrashHandler {
// Print log message by invoking LoggerImpl#print
Logger.getLoggerImplementation().print(LogLevel.CRASH, logIssuer, base);
// Emit EngineCrashEvent
new EngineCrashEvent().callEvent();
// Emit event
if (throwableHandled)
new EngineSoftCrashEvent().callEvent();
else
new EngineCrashEvent().callEvent();
// Shutdown (engine &) JVM
if (EngineConfiguration.getInstance().isLoggerImmediateShutdown())
Runtime.getRuntime().halt(69);
else
Engine.getInstance().shutdown(69);
if (!throwableHandled)
if (EngineConfiguration.getInstance().isLoggerImmediateShutdown())
Runtime.getRuntime().halt(69);
else
Engine.getInstance().shutdown(69);
}
/**

View file

@ -308,6 +308,19 @@ public final class Logger {
log(logIssuer, LogLevel.ERROR, message);
}
/**
* Crashes the entire engine.
*
* @param logIssuer issuing class
* @param message diagnostic message
* @param throwable the throwable that caused this crash
* @param handled declare the throwable has handled
* @since 1-alpha0
*/
public static void crash(@NotNull LogIssuer logIssuer, @NotNull String message, @NotNull Throwable throwable, boolean handled) {
CrashHandler.handleCrash(logIssuer, message, throwable, handled);
}
/**
* Crashes the entire engine.
*
@ -317,7 +330,7 @@ public final class Logger {
* @since 1-alpha0
*/
public static void crash(@NotNull LogIssuer logIssuer, @NotNull String message, @NotNull Throwable throwable) {
CrashHandler.handleCrash(logIssuer, message, throwable);
CrashHandler.handleCrash(logIssuer, message, throwable, false);
}
/**
@ -328,6 +341,6 @@ public final class Logger {
* @since 1-alpha0
*/
public static void crash(@NotNull LogIssuer logIssuer, @NotNull String message) {
CrashHandler.handleCrash(logIssuer, message, null);
CrashHandler.handleCrash(logIssuer, message, null, false);
}
}

View file

@ -115,6 +115,19 @@ public final class LoggerInstance {
Logger.error(logIssuer, message);
}
/**
* Crashes the entire engine.
*
* @param message diagnostic message
* @param throwable throwable that caused this crash
* @param handled declare the throwable has handled
* @see CrashHandler
* @since 1-alpha0
*/
public void crash(@NotNull String message, @NotNull Throwable throwable, boolean handled) {
Logger.crash(logIssuer, message, throwable, handled);
}
/**
* Crashes the entire engine.
*