From 80612cc35550a6e5196b83287d147bb9a137c4c2 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:19:17 -0700 Subject: [PATCH 1/4] make filtering consumer-specific. --- .../njol/skript/sections/SecCatchErrors.java | 1 - .../log/runtime/RuntimeErrorCatcher.java | 52 +++------ .../log/runtime/RuntimeErrorConsumer.java | 11 ++ .../log/runtime/RuntimeErrorFilter.java | 48 ++++++++ .../log/runtime/RuntimeErrorManager.java | 107 +++++++++++------- .../expressions/ExprWorldBorderCenter.sk | 6 + 6 files changed, 147 insertions(+), 78 deletions(-) create mode 100644 src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java diff --git a/src/main/java/ch/njol/skript/sections/SecCatchErrors.java b/src/main/java/ch/njol/skript/sections/SecCatchErrors.java index 2fd40b57a1f..fad8e88caf0 100644 --- a/src/main/java/ch/njol/skript/sections/SecCatchErrors.java +++ b/src/main/java/ch/njol/skript/sections/SecCatchErrors.java @@ -68,7 +68,6 @@ public boolean isSatisfiedBy(ExperimentSet experimentSet) { TriggerItem.walk(first, event); ExprCaughtErrors.lastErrors = catcher.getCachedErrors().stream().map(RuntimeError::error).toArray(String[]::new); catcher.clearCachedErrors() - .clearCachedFrames() .stop(); return walk(event, false); } diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java index 65d5fc04152..c9a281a253a 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java @@ -1,13 +1,14 @@ package org.skriptlang.skript.log.runtime; +import ch.njol.skript.Skript; import ch.njol.skript.log.SkriptLogger; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import org.skriptlang.skript.log.runtime.Frame.FrameOutput; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map.Entry; import java.util.logging.Level; /** @@ -20,7 +21,8 @@ public class RuntimeErrorCatcher implements RuntimeErrorConsumer { private final List cachedErrors = new ArrayList<>(); - private final List> cachedFrames = new ArrayList<>(); + // hard limit on stored errors to prevent a runaway loop from filling up memory, for example. + private static final int ERROR_LIMIT = 1000; public RuntimeErrorCatcher() {} @@ -28,7 +30,12 @@ public RuntimeErrorCatcher() {} * Gets the {@link RuntimeErrorManager}. */ private RuntimeErrorManager getManager() { - return RuntimeErrorManager.getInstance(); + return Skript.getRuntimeErrorManager(); + } + + @Override + public @Nullable RuntimeErrorFilter getFilter() { + return null; // no filter means everything gets printed. } /** @@ -47,7 +54,7 @@ public RuntimeErrorCatcher start() { /** * Stops this {@link RuntimeErrorCatcher}, removing from {@link RuntimeErrorManager} and restoring the previous * {@link RuntimeErrorConsumer}s from {@link #storedConsumers}. - * Prints all cached {@link RuntimeError}s, {@link #cachedErrors}, and cached {@link FrameOutput}s, {@link #cachedFrames}. + * Prints all cached {@link RuntimeError}s, {@link #cachedErrors}. */ public void stop() { if (!getManager().removeConsumer(this)) { @@ -57,8 +64,6 @@ public void stop() { getManager().addConsumers(storedConsumers.toArray(RuntimeErrorConsumer[]::new)); for (RuntimeError runtimeError : cachedErrors) storedConsumers.forEach(consumer -> consumer.printError(runtimeError)); - for (Entry entry : cachedFrames) - storedConsumers.forEach(consumer -> consumer.printFrameOutput(entry.getKey(), entry.getValue())); } /** @@ -68,13 +73,6 @@ public void stop() { return Collections.unmodifiableList(cachedErrors); } - /** - * Gets all cached {@link FrameOutput}s stored with its corresponding {@link Level} in an {@link Entry} - */ - public @UnmodifiableView List> getCachedFrames() { - return Collections.unmodifiableList(cachedFrames); - } - /** * Clear all cached {@link RuntimeError}s. */ @@ -83,37 +81,15 @@ public RuntimeErrorCatcher clearCachedErrors() { return this; } - /** - * Clears all cached {@link FrameOutput}s. - */ - public RuntimeErrorCatcher clearCachedFrames() { - cachedFrames.clear(); - return this; - } - @Override public void printError(RuntimeError error) { - cachedErrors.add(error); + if (cachedErrors.size() < ERROR_LIMIT) + cachedErrors.add(error); } @Override public void printFrameOutput(FrameOutput output, Level level) { - cachedFrames.add(new Entry() { - @Override - public FrameOutput getKey() { - return output; - } - - @Override - public Level getValue() { - return level; - } - - @Override - public Level setValue(Level value) { - return null; - } - }); + // do nothing, this won't be called since we have no filter. } } diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java index 21d271bfaca..949c74aba1c 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java @@ -1,5 +1,7 @@ package org.skriptlang.skript.log.runtime; +import org.jetbrains.annotations.Nullable; + import java.util.logging.Level; /** @@ -15,6 +17,15 @@ public interface RuntimeErrorConsumer { */ void printError(RuntimeError error); + /** + * @return The filter to use when checking if this consumer should print an error. Defaults to the standard + * config-driven filter. May be null if no filter should be used (also disables frame outputs). This value + * MUST be effectively final. + */ + default @Nullable RuntimeErrorFilter getFilter() { + return RuntimeErrorManager.standardFilter; + } + /** * Prints the output of a frame, including skipped errors, timeouts, and whatever other information required. * @param output An output object containing unmodifiable views of the frame data. diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java new file mode 100644 index 00000000000..9ec838ec470 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java @@ -0,0 +1,48 @@ +package org.skriptlang.skript.log.runtime; + +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Level; + +public class RuntimeErrorFilter { + + private Frame errorFrame, warningFrame; + + public RuntimeErrorFilter(Frame.FrameLimit errorFrameLimits, Frame.FrameLimit warningFrameLimits) { + this.errorFrame = new Frame(errorFrameLimits); + this.warningFrame = new Frame(warningFrameLimits); + } + + /** + * Tests whether a runtime error should be printed or not. + * @param error True if it should be printed, false if not. + */ + public boolean test(@NotNull RuntimeError error) { + // print if < limit + return (error.level() == Level.SEVERE && errorFrame.add(error)) + || (error.level() == Level.WARNING && warningFrame.add(error)); + } + + public void setErrorFrameLimits(Frame.FrameLimit limits) { + this.errorFrame = new Frame(limits); + } + + public void setWarningFrameLimits(Frame.FrameLimit limits) { + this.warningFrame = new Frame(limits); + } + + /** + * @return The frame containing emitted errors. + */ + public Frame getErrorFrame() { + return errorFrame; + } + + /** + * @return The frame containing emitted warnings. + */ + public Frame getWarningFrame() { + return warningFrame; + } + +} diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java index 6389156dfc5..9b0a354e030 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java @@ -9,9 +9,7 @@ import org.skriptlang.skript.log.runtime.Frame.FrameLimit; import java.io.Closeable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import java.util.logging.Level; /** @@ -39,38 +37,45 @@ public static RuntimeErrorManager getInstance() { return instance; } + static RuntimeErrorFilter standardFilter; + /** * Refreshes the runtime error manager for Skript, pulling from the config values. * Tracked consumers are maintained during refreshes. */ public static void refresh() { long frameLength = SkriptConfig.runtimeErrorFrameDuration.value().getAs(Timespan.TimePeriod.TICK); + if (instance == null) { + instance = new RuntimeErrorManager(frameLength); + } else { + var oldMap = instance.filterMap; + instance = new RuntimeErrorManager(frameLength); + instance.filterMap.putAll(oldMap); + } int errorLimit = SkriptConfig.runtimeErrorLimitTotal.value(); int errorLineLimit = SkriptConfig.runtimeErrorLimitLine.value(); int errorLineTimeout = SkriptConfig.runtimeErrorLimitLineTimeout.value(); int errorTimeoutLength = Math.max(SkriptConfig.runtimeErrorTimeoutDuration.value(), 1); - FrameLimit errorFrame = new FrameLimit(errorLimit, errorLineLimit, errorLineTimeout, errorTimeoutLength); + var errorLimits = new FrameLimit(errorLimit, errorLineLimit, errorLineTimeout, errorTimeoutLength); int warningLimit = SkriptConfig.runtimeWarningLimitTotal.value(); int warningLineLimit = SkriptConfig.runtimeWarningLimitLine.value(); int warningLineTimeout = SkriptConfig.runtimeWarningLimitLineTimeout.value(); int warningTimeoutLength = Math.max(SkriptConfig.runtimeWarningTimeoutDuration.value(), 1); - FrameLimit warningFrame = new FrameLimit(warningLimit, warningLineLimit, warningLineTimeout, warningTimeoutLength); + var warningsLimits = new FrameLimit(warningLimit, warningLineLimit, warningLineTimeout, warningTimeoutLength); - List oldConsumers = List.of(); - if (instance != null) { - instance.close(); - oldConsumers = instance.consumers; + if (standardFilter == null) { + standardFilter = new RuntimeErrorFilter(errorLimits, warningsLimits); + } else { + standardFilter.setErrorFrameLimits(errorLimits); + standardFilter.setWarningFrameLimits(warningsLimits); } - instance = new RuntimeErrorManager(Math.max((int) frameLength, 1), errorFrame, warningFrame); - oldConsumers.forEach(consumer -> instance.addConsumer(consumer)); } - private final Frame errorFrame, warningFrame; private final Task task; - private final List consumers = new ArrayList<>(); + private final Map> filterMap = new HashMap<>(); /** * Creates a new error manager, which also creates its own frames. @@ -78,48 +83,59 @@ public static void refresh() { * Must be closed when no longer being used. * * @param frameLength The length of a frame in ticks. - * @param errorLimits The limits to the error frame. - * @param warningLimits The limits to the warning frame. */ - public RuntimeErrorManager(int frameLength, FrameLimit errorLimits, FrameLimit warningLimits) { - errorFrame = new Frame(errorLimits); - warningFrame = new Frame(warningLimits); + public RuntimeErrorManager(long frameLength) { task = new Task(Skript.getInstance(), frameLength, frameLength, true) { @Override public void run() { - consumers.forEach(consumer -> consumer.printFrameOutput(errorFrame.getFrameOutput(), Level.SEVERE)); - errorFrame.nextFrame(); - - consumers.forEach(consumer -> consumer.printFrameOutput(warningFrame.getFrameOutput(), Level.WARNING)); - warningFrame.nextFrame(); + for (var entry : filterMap.entrySet()) { + RuntimeErrorFilter filter = entry.getKey(); + if (filter == null) + continue; + Set consumers = entry.getValue(); + + Frame errorFrame = filter.getErrorFrame(); + consumers.forEach(consumer -> consumer.printFrameOutput(errorFrame.getFrameOutput(), Level.SEVERE)); + errorFrame.nextFrame(); + + Frame warningFrame = filter.getErrorFrame(); + consumers.forEach(consumer -> consumer.printFrameOutput(warningFrame.getFrameOutput(), Level.WARNING)); + warningFrame.nextFrame(); + } } }; } /** - * Emits a warning or error depending on severity. Errors are passed to their respective {@link Frame}s for processing. + * Emits a warning or error depending on severity. * @param error The error to emit. */ public void error(@NotNull RuntimeError error) { - // print if < limit - if ((error.level() == Level.SEVERE && errorFrame.add(error)) - || (error.level() == Level.WARNING && warningFrame.add(error))) { - consumers.forEach((consumer -> consumer.printError(error))); + for (var entry : filterMap.entrySet()) { + RuntimeErrorFilter filter = entry.getKey(); + Set consumers = entry.getValue(); + if (filter == null || filter.test(error)){ + consumers.forEach((consumer -> consumer.printError(error))); + } } } /** * @return The frame containing emitted errors. + * @deprecated {@link RuntimeErrorFilter#getErrorFrame()} */ + @Deprecated(since="INSERT VERSION", forRemoval = true) public Frame getErrorFrame() { - return errorFrame; + return standardFilter.getErrorFrame(); } /** * @return The frame containing emitted warnings. + * @deprecated {@link RuntimeErrorFilter#getWarningFrame()} */ + @Deprecated(since="INSERT VERSION", forRemoval = true) public Frame getWarningFrame() { - return warningFrame; + return standardFilter.getWarningFrame(); } /** @@ -128,8 +144,8 @@ public Frame getWarningFrame() { * @param consumer The consumer to add. */ public void addConsumer(RuntimeErrorConsumer consumer) { - synchronized (consumers) { - consumers.add(consumer); + synchronized (filterMap) { + filterMap.computeIfAbsent(consumer.getFilter(), key -> new HashSet<>()).add(consumer); } } @@ -139,8 +155,10 @@ public void addConsumer(RuntimeErrorConsumer consumer) { * @param newConsumers The {@link RuntimeErrorConsumer}s to add. */ public void addConsumers(RuntimeErrorConsumer... newConsumers) { - synchronized (consumers) { - consumers.addAll(Arrays.asList(newConsumers)); + synchronized (filterMap) { + for (var consumer : newConsumers) { + filterMap.computeIfAbsent(consumer.getFilter(), key -> new HashSet<>()).add(consumer); + } } } @@ -150,9 +168,19 @@ public void addConsumers(RuntimeErrorConsumer... newConsumers) { * @return {@code true} If the {@code consumer} was removed. */ public boolean removeConsumer(RuntimeErrorConsumer consumer) { - synchronized (consumers) { - return consumers.remove(consumer); + synchronized (filterMap) { + var iterator = filterMap.entrySet().iterator(); + while (iterator.hasNext()) { + var entry = iterator.next(); + boolean removed = entry.getValue().remove(consumer); + if (entry.getValue().isEmpty()) { + iterator.remove(); + } + if (removed) + return true; + } } + return false; } /** @@ -160,9 +188,10 @@ public boolean removeConsumer(RuntimeErrorConsumer consumer) { * @return All {@link RuntimeErrorConsumer}s removed. */ public List removeAllConsumers() { - synchronized (consumers) { - List currentConsumers = List.copyOf(consumers); - consumers.clear(); + synchronized (filterMap) { + List currentConsumers = new ArrayList<>(); + for (var set : filterMap.values()) + currentConsumers.addAll(set); return currentConsumers; } } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprWorldBorderCenter.sk b/src/test/skript/tests/syntaxes/expressions/ExprWorldBorderCenter.sk index da7ae6ea1f8..825306ef251 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprWorldBorderCenter.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprWorldBorderCenter.sk @@ -36,3 +36,9 @@ test "worldborder center": reset worldborder center of {_border} assert worldborder center of {_border} is location(0, 0, 0, "world") with "failed to reset border center" + + catch runtime errors: + loop 20 times: + set worldborder center of {_border} to location(2, 0, NaN value) + set worldborder damage amount of {_border} to infinity value + assert last caught runtime errors contains "World border damage amount cannot be infinite" with "Infinity damage value did not throw error" From 4fd4766f922a63f2cd771ee8ba071f2231ad7131 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:22:27 -0700 Subject: [PATCH 2/4] better remove() --- .../log/runtime/RuntimeErrorManager.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java index 9b0a354e030..0a628c6fd2e 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java @@ -169,18 +169,14 @@ public void addConsumers(RuntimeErrorConsumer... newConsumers) { */ public boolean removeConsumer(RuntimeErrorConsumer consumer) { synchronized (filterMap) { - var iterator = filterMap.entrySet().iterator(); - while (iterator.hasNext()) { - var entry = iterator.next(); - boolean removed = entry.getValue().remove(consumer); - if (entry.getValue().isEmpty()) { - iterator.remove(); - } - if (removed) - return true; - } + var set = filterMap.get(consumer.getFilter()); + if (set == null) + return false; + boolean removed = set.remove(consumer); + if (set.isEmpty()) + filterMap.remove(consumer.getFilter()); + return removed; } - return false; } /** From 6c5f0371f5a7fa83185dc8f4b52426b36f7120d6 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:54:59 -0700 Subject: [PATCH 3/4] Requested Changes --- .../skriptlang/skript/log/runtime/RuntimeErrorFilter.java | 6 ++++++ .../skriptlang/skript/log/runtime/RuntimeErrorManager.java | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java index 9ec838ec470..2f6b1ce20ec 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java @@ -4,6 +4,12 @@ import java.util.logging.Level; +/** + * Handles filtering of runtime errors based on their level and predefined limits. + * Uses the concept of 'frames' to track the number of errors and warnings that are allowed in a given period. + * Use {@link #test(RuntimeError)} to determine if a runtime error should be printed or not. + * Printing the frame outputs can be done via {@link #getErrorFrame()} and {@link #getWarningFrame()}. + */ public class RuntimeErrorFilter { private Frame errorFrame, warningFrame; diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java index 0a628c6fd2e..63750d82364 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorManager.java @@ -10,6 +10,7 @@ import java.io.Closeable; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; /** @@ -57,13 +58,13 @@ public static void refresh() { int errorLineLimit = SkriptConfig.runtimeErrorLimitLine.value(); int errorLineTimeout = SkriptConfig.runtimeErrorLimitLineTimeout.value(); int errorTimeoutLength = Math.max(SkriptConfig.runtimeErrorTimeoutDuration.value(), 1); - var errorLimits = new FrameLimit(errorLimit, errorLineLimit, errorLineTimeout, errorTimeoutLength); + FrameLimit errorLimits = new FrameLimit(errorLimit, errorLineLimit, errorLineTimeout, errorTimeoutLength); int warningLimit = SkriptConfig.runtimeWarningLimitTotal.value(); int warningLineLimit = SkriptConfig.runtimeWarningLimitLine.value(); int warningLineTimeout = SkriptConfig.runtimeWarningLimitLineTimeout.value(); int warningTimeoutLength = Math.max(SkriptConfig.runtimeWarningTimeoutDuration.value(), 1); - var warningsLimits = new FrameLimit(warningLimit, warningLineLimit, warningLineTimeout, warningTimeoutLength); + FrameLimit warningsLimits = new FrameLimit(warningLimit, warningLineLimit, warningLineTimeout, warningTimeoutLength); if (standardFilter == null) { standardFilter = new RuntimeErrorFilter(errorLimits, warningsLimits); @@ -75,7 +76,7 @@ public static void refresh() { private final Task task; - private final Map> filterMap = new HashMap<>(); + private final Map> filterMap = new ConcurrentHashMap<>(); /** * Creates a new error manager, which also creates its own frames. From 0a8b735a28156bc2f1acb45c2e06da2faadb0d09 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Tue, 30 Sep 2025 19:11:55 -0700 Subject: [PATCH 4/4] avoid null --- .../skript/log/runtime/RuntimeErrorCatcher.java | 2 +- .../skript/log/runtime/RuntimeErrorConsumer.java | 2 +- .../skript/log/runtime/RuntimeErrorFilter.java | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java index c9a281a253a..2367c47d901 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorCatcher.java @@ -35,7 +35,7 @@ private RuntimeErrorManager getManager() { @Override public @Nullable RuntimeErrorFilter getFilter() { - return null; // no filter means everything gets printed. + return RuntimeErrorFilter.NO_FILTER; // no filter means everything gets printed. } /** diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java index 949c74aba1c..fd2ac49c2cc 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorConsumer.java @@ -19,7 +19,7 @@ public interface RuntimeErrorConsumer { /** * @return The filter to use when checking if this consumer should print an error. Defaults to the standard - * config-driven filter. May be null if no filter should be used (also disables frame outputs). This value + * config-driven filter. If no filter should be used, return {@link RuntimeErrorFilter#NO_FILTER}. This value * MUST be effectively final. */ default @Nullable RuntimeErrorFilter getFilter() { diff --git a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java index 2f6b1ce20ec..46bdb6ad7d8 100644 --- a/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java +++ b/src/main/java/org/skriptlang/skript/log/runtime/RuntimeErrorFilter.java @@ -12,6 +12,20 @@ */ public class RuntimeErrorFilter { + /** + * A filter that does not filter anything, allowing all errors and warnings to be printed. + * Modifications to its limits will do nothing, and the returned frames will hold no relevant data. + */ + public static final RuntimeErrorFilter NO_FILTER = new RuntimeErrorFilter( + new Frame.FrameLimit(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE), + new Frame.FrameLimit(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE) + ) { + @Override + public boolean test(@NotNull RuntimeError error) { + return true; + } + }; + private Frame errorFrame, warningFrame; public RuntimeErrorFilter(Frame.FrameLimit errorFrameLimits, Frame.FrameLimit warningFrameLimits) {