diff --git a/core/src/main/java/dev/faststats/core/ErrorTracker.java b/core/src/main/java/dev/faststats/core/ErrorTracker.java index 478b4d8..d9e7280 100644 --- a/core/src/main/java/dev/faststats/core/ErrorTracker.java +++ b/core/src/main/java/dev/faststats/core/ErrorTracker.java @@ -1,10 +1,12 @@ package dev.faststats.core; +import org.intellij.lang.annotations.RegExp; import org.jetbrains.annotations.Contract; import org.jspecify.annotations.Nullable; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.regex.Pattern; /** * An error tracker. @@ -96,6 +98,85 @@ static ErrorTracker contextUnaware() { @Contract(mutates = "this") void trackError(Throwable error, boolean handled); + /** + * Adds an error type that will not be reported to FastStats. + *
+ * Matching is done exactly. If, for example {@link LinkageError} was ignored, + * {@link NoClassDefFoundError} would still be reported, even though it extends {@link LinkageError} + * + * @param type the error type + * @return the error tracker + * @since 0.21.0 + */ + @Contract(value = "_ -> this", mutates = "this") + ErrorTracker ignoreErrorType(Class extends Throwable> type); + + /** + * Adds a pattern that will be matched against all error messages. + *
+ * If an error's message matches the given pattern, it will not be reported to FastStats. + *
{@code
+ * // Exact match
+ * tracker.ignoreError(Pattern.compile("No space left on device"));
+ *
+ * // Regex match
+ * tracker.ignoreError(Pattern.compile("No serializer for: class .*"));
+ * }
+ *
+ * @param pattern the regex pattern to match against error messages
+ * @return the error tracker
+ * @since 0.21.0
+ */
+ @Contract(value = "_ -> this", mutates = "this")
+ ErrorTracker ignoreError(Pattern pattern);
+
+ /**
+ * Adds a pattern that will be matched against all error messages.
+ * + * If an error's message matches the given pattern, it will not be reported to FastStats. + * + * @param pattern the regex pattern string to match against error messages + * @return the error tracker + * @see #ignoreError(Pattern) + * @since 0.21.0 + */ + @Contract(value = "_ -> this", mutates = "this") + default ErrorTracker ignoreError(@RegExp final String pattern) { + return ignoreError(Pattern.compile(pattern)); + } + + /** + * Adds an error type combined with a message pattern that will not be reported to FastStats. + *
+ * An error is ignored only if its class matches the given type exactly and its message matches the given pattern. + *
{@code
+ * tracker.ignoreError(IOException.class, Pattern.compile("No space left on device"));
+ * }
+ *
+ * @param type the error type
+ * @param pattern the regex pattern to match against error messages
+ * @return the error tracker
+ * @since 0.21.0
+ */
+ @Contract(value = "_, _ -> this", mutates = "this")
+ ErrorTracker ignoreError(Class extends Throwable> type, Pattern pattern);
+
+ /**
+ * Adds an error type combined with a message pattern that will not be reported to FastStats.
+ * + * An error is ignored only if its class matches the given type exactly and its message matches the given pattern. + * + * @param type the error type + * @param pattern the regex pattern string to match against error messages + * @return the error tracker + * @see #ignoreError(Class, Pattern) + * @since 0.21.0 + */ + @Contract(value = "_, _ -> this", mutates = "this") + default ErrorTracker ignoreError(final Class extends Throwable> type, @RegExp final String pattern) { + return ignoreError(type, Pattern.compile(pattern)); + } + /** * Attaches an error context to the tracker. *
diff --git a/core/src/main/java/dev/faststats/core/SimpleErrorTracker.java b/core/src/main/java/dev/faststats/core/SimpleErrorTracker.java
index e10165d..f30eb0d 100644
--- a/core/src/main/java/dev/faststats/core/SimpleErrorTracker.java
+++ b/core/src/main/java/dev/faststats/core/SimpleErrorTracker.java
@@ -5,15 +5,25 @@
import org.jspecify.annotations.Nullable;
import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Collections;
+import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiConsumer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
final class SimpleErrorTracker implements ErrorTracker {
private final Map