Add option to completely hide a crash-callable depending on a runtime value (#9372)

This commit is contained in:
Dennis C authored and GitHub committed 2023-03-20 14:15:59 -07:00
1 parent 7b8ca60d32
commit 684d36201f
5 files changed
+118 -8

No files matched your search

@@ -5,33 +5,93 @@
package net.minecraftforge.fml;
import com.mojang.logging.LogUtils;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
public class CrashReportCallables {
public class CrashReportCallables
{
private static final Logger LOGGER = LogUtils.getLogger();
private static final List<ISystemReportExtender> crashCallables = Collections.synchronizedList(new ArrayList<>());
/**
* Register a custom {@link ISystemReportExtender}
*/
public static void registerCrashCallable(ISystemReportExtender callable)
{
crashCallables.add(callable);
}
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator) {
registerCrashCallable(new ISystemReportExtender() {
/**
* Register a {@link ISystemReportExtender system report extender} with the given header name and content
* generator, which will always be appended to the system report
* @param headerName The name of the system report entry
* @param reportGenerator The report generator to be called when a crash report is built
*/
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator)
{
registerCrashCallable(new ISystemReportExtender()
{
@Override
public String getLabel() {
public String getLabel()
{
return headerName;
}
@Override
public String get() {
public String get()
{
return reportGenerator.get();
}
});
}
public static List<ISystemReportExtender> allCrashCallables() {
/**
* Register a {@link ISystemReportExtender system report extender} with the given header name and content
* generator, which will only be appended to the system report when the given {@link BooleanSupplier} returns true
* @param headerName The name of the system report entry
* @param reportGenerator The report generator to be called when a crash report is built
* @param active The supplier of the flag to be checked when a crash report is built
*/
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator, BooleanSupplier active)
{
registerCrashCallable(new ISystemReportExtender()
{
@Override
public String getLabel()
{
return headerName;
}
@Override
public String get()
{
return reportGenerator.get();
}
@Override
public boolean isActive()
{
try
{
return active.getAsBoolean();
}
catch (Throwable t)
{
LOGGER.warn("CrashCallable '{}' threw an exception while checking the active flag, disabling", headerName, t);
return false;
}
}
});
}
public static List<ISystemReportExtender> allCrashCallables()
{
return List.copyOf(crashCallables);
}
}
@@ -10,4 +10,9 @@ import java.util.function.Supplier;
public interface ISystemReportExtender extends Supplier<String>
{
String getLabel();
default boolean isActive()
{
return true;
}
}
@@ -26,9 +26,12 @@ public class CrashReportExtender
public static void extendSystemReport(final SystemReport systemReport)
{
for (final ISystemReportExtender call: CrashReportCallables.allCrashCallables())
for (final ISystemReportExtender call : CrashReportCallables.allCrashCallables())
{
systemReport.setDetail(call.getLabel(), call);
if (call.isActive())
{
systemReport.setDetail(call.getLabel(), call);
}
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
package net.minecraftforge.debug;
import net.minecraftforge.fml.CrashReportCallables;
import net.minecraftforge.fml.common.Mod;
/**
* Test features and guards of crash-callables.
* <ul>
* <li>The "AlwaysActiveCrashCallable" must always be printed to the crash report</li>
* <li>The "ToggleableCrashCallable" must only be printed to the crash report when the {@code ENABLED} flag is {@code true}</li>
* <li>The "BadContentCrashCallable" must always print "BadContentCrashCallable: ERR" to the crash report and
* print an exception to the log (relies on a try-catch in vanilla code)</li>
* <li>The "BadFlagCrashCallable" must never print to the crash report and must print an exception to the log</li>
* </ul>
* To initiate a debug crash to test this, hold F3 + C for 10 seconds.
*/
@Mod("crash_callable_test")
public class CrashCallableTest
{
private static final boolean ENABLED = true;
public CrashCallableTest()
{
CrashReportCallables.registerCrashCallable("AlwaysActiveCrashCallable", () -> "test");
CrashReportCallables.registerCrashCallable("ToggleableCrashCallable", () -> "active", () -> ENABLED);
CrashReportCallables.registerCrashCallable("BadContentCrashCallable", () ->
{
throw new UnsupportedOperationException();
});
CrashReportCallables.registerCrashCallable("BadFlagCrashCallable", () -> "why am I here?!", () ->
{
throw new UnsupportedOperationException();
});
}
}
+2
View File
@@ -21,6 +21,8 @@ license="LGPL v2.1"
modId="advancement_event_test"
[[mods]]
modId="shader_resources_test"
[[mods]]
modId="crash_callable_test"
# LEGACY TEST CASES
###### The mods below are from the old test framework and need to be yeeted later again.