Skip to content

Commit

Permalink
implement ignoredErrors instead of ignoredExceptions, matching on sev…
Browse files Browse the repository at this point in the history
…eral possible messages as in the JS SDK and not on only on the Exception class
  • Loading branch information
lcian committed Jan 23, 2025
1 parent 14518c3 commit 6e78fd0
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 112 deletions.
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

### Features

- Add `options.ignoreExceptions` to filter out exceptions that match a certain String or Regex ([#4083](https://github.com/getsentry/sentry-java/pull/4083))
- Can be set in `sentry.properties`, e.g. `ignored-exceptions=java.lang.RuntimeException,io.sentry..*`
- Can be set in environment variables, e.g. `SENTRY_IGNORED_EXCEPTIONS=java.lang.RuntimeException,io.sentry..*`
- For Spring Boot, it can be set in `application.properties`, e.g. `sentry.ignored-exceptions=java.lang.RuntimeException,io.sentry..*`
- Add `options.ignoredErrors` to filter out errors that match a certain String or Regex ([#4083](https://github.com/getsentry/sentry-java/pull/4083))
- Can be set in `sentry.properties`, e.g. `ignored-errors=Some error,Another .*`
- Can be set in environment variables, e.g. `SENTRY_IGNORED_ERRORS=Some error,Another .*`
- For Spring Boot, it can be set in `application.properties`, e.g. `sentry.ignored-errors=Some error,Another .*`

## 8.0.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-exceptions=com.some.Exception,io.sentry..*",
"sentry.ignored-errors=Some error,Another .*",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.enable-backpressure-handling=false",
"sentry.enable-spotlight=true",
Expand Down Expand Up @@ -216,7 +216,7 @@ class SentryAutoConfigurationTest {
assertThat(options.isEnabled).isEqualTo(false)
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB"))
assertThat(options.ignoredExceptions).containsOnly(FilterString("com.some.Exception"), FilterString("io.sentry..*"))
assertThat(options.ignoredErrors).containsOnly(FilterString("Some error"), FilterString("Another .*"))
assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB"))
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isForceInit).isEqualTo(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-exceptions=com.some.Exception,io.sentry..*",
"sentry.ignored-errors=Some error,Another .*",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.enable-backpressure-handling=false",
"sentry.enable-spotlight=true",
Expand Down Expand Up @@ -215,7 +215,7 @@ class SentryAutoConfigurationTest {
assertThat(options.isEnabled).isEqualTo(false)
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB"))
assertThat(options.ignoredExceptions).containsOnly(FilterString("com.some.Exception"), FilterString("io.sentry..*"))
assertThat(options.ignoredErrors).containsOnly(FilterString("Some error"), FilterString("Another .*"))
assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB"))
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isForceInit).isEqualTo(true)
Expand Down
18 changes: 11 additions & 7 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ public final class io/sentry/ExternalOptions {
public fun <init> ()V
public fun addBundleId (Ljava/lang/String;)V
public fun addContextTag (Ljava/lang/String;)V
public fun addIgnoredException (Ljava/lang/String;)V
public fun addIgnoredExceptionForType (Ljava/lang/Class;)V
public fun addInAppExclude (Ljava/lang/String;)V
public fun addInAppInclude (Ljava/lang/String;)V
Expand All @@ -453,7 +452,7 @@ public final class io/sentry/ExternalOptions {
public fun getEnvironment ()Ljava/lang/String;
public fun getIdleTimeout ()Ljava/lang/Long;
public fun getIgnoredCheckIns ()Ljava/util/List;
public fun getIgnoredExceptions ()Ljava/util/List;
public fun getIgnoredErrors ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredTransactions ()Ljava/util/List;
public fun getInAppExcludes ()Ljava/util/List;
Expand Down Expand Up @@ -493,7 +492,7 @@ public final class io/sentry/ExternalOptions {
public fun setGlobalHubMode (Ljava/lang/Boolean;)V
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredExceptions (Ljava/util/List;)V
public fun setIgnoredErrors (Ljava/util/List;)V
public fun setIgnoredTransactions (Ljava/util/List;)V
public fun setMaxRequestBodySize (Lio/sentry/SentryOptions$RequestSize;)V
public fun setPrintUncaughtStackTrace (Ljava/lang/Boolean;)V
Expand Down Expand Up @@ -2817,7 +2816,7 @@ public class io/sentry/SentryOptions {
public fun addContextTag (Ljava/lang/String;)V
public fun addEventProcessor (Lio/sentry/EventProcessor;)V
public fun addIgnoredCheckIn (Ljava/lang/String;)V
public fun addIgnoredException (Ljava/lang/String;)V
public fun addIgnoredError (Ljava/lang/String;)V
public fun addIgnoredExceptionForType (Ljava/lang/Class;)V
public fun addIgnoredSpanOrigin (Ljava/lang/String;)V
public fun addIgnoredTransaction (Ljava/lang/String;)V
Expand Down Expand Up @@ -2859,7 +2858,7 @@ public class io/sentry/SentryOptions {
public fun getGestureTargetLocators ()Ljava/util/List;
public fun getIdleTimeout ()Ljava/lang/Long;
public fun getIgnoredCheckIns ()Ljava/util/List;
public fun getIgnoredExceptions ()Ljava/util/List;
public fun getIgnoredErrors ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredSpanOrigins ()Ljava/util/List;
public fun getIgnoredTransactions ()Ljava/util/List;
Expand Down Expand Up @@ -2992,7 +2991,7 @@ public class io/sentry/SentryOptions {
public fun setGlobalHubMode (Ljava/lang/Boolean;)V
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredExceptions (Ljava/util/List;)V
public fun setIgnoredErrors (Ljava/util/List;)V
public fun setIgnoredSpanOrigins (Ljava/util/List;)V
public fun setIgnoredTransactions (Ljava/util/List;)V
public fun setInitPriority (Lio/sentry/InitPriority;)V
Expand Down Expand Up @@ -6053,6 +6052,11 @@ public final class io/sentry/util/DebugMetaPropertiesApplier {
public static fun getProguardUuid (Ljava/util/Properties;)Ljava/lang/String;
}

public final class io/sentry/util/ErrorUtils {
public fun <init> ()V
public static fun isIgnored (Ljava/util/List;Lio/sentry/SentryEvent;)Z
}

public final class io/sentry/util/EventProcessorUtils {
public fun <init> ()V
public static fun unwrap (Ljava/util/List;)Ljava/util/List;
Expand All @@ -6061,7 +6065,7 @@ public final class io/sentry/util/EventProcessorUtils {
public final class io/sentry/util/ExceptionUtils {
public fun <init> ()V
public static fun findRootCause (Ljava/lang/Throwable;)Ljava/lang/Throwable;
public static fun isIgnored (Ljava/util/Set;Ljava/util/List;Ljava/lang/Throwable;)Z
public static fun isIgnored (Ljava/util/Set;Ljava/lang/Throwable;)Z
}

public final class io/sentry/util/FileUtils {
Expand Down
19 changes: 6 additions & 13 deletions sentry/src/main/java/io/sentry/ExternalOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public final class ExternalOptions {
private @Nullable Long idleTimeout;
private final @NotNull Set<Class<? extends Throwable>> ignoredExceptionsForType =
new CopyOnWriteArraySet<>();
private @Nullable List<String> ignoredExceptions;
private @Nullable List<String> ignoredErrors;
private @Nullable Boolean printUncaughtStackTrace;
private @Nullable Boolean sendClientReports;
private @NotNull Set<String> bundleIds = new CopyOnWriteArraySet<>();
Expand Down Expand Up @@ -128,7 +128,7 @@ public final class ExternalOptions {
}
options.setIdleTimeout(propertiesProvider.getLongProperty("idle-timeout"));

options.setIgnoredExceptions(propertiesProvider.getList("ignored-exceptions"));
options.setIgnoredErrors(propertiesProvider.getList("ignored-errors"));

options.setEnabled(propertiesProvider.getBooleanProperty("enabled"));

Expand Down Expand Up @@ -373,19 +373,12 @@ public void setIdleTimeout(final @Nullable Long idleTimeout) {
this.idleTimeout = idleTimeout;
}

public @Nullable List<String> getIgnoredExceptions() {
return ignoredExceptions;
public @Nullable List<String> getIgnoredErrors() {
return ignoredErrors;
}

public void setIgnoredExceptions(final @Nullable List<String> ignoredExceptions) {
this.ignoredExceptions = ignoredExceptions;
}

public void addIgnoredException(final @NotNull String pattern) {
if (ignoredExceptions == null) {
ignoredExceptions = new ArrayList<>();
}
ignoredExceptions.add(pattern);
public void setIgnoredErrors(final @Nullable List<String> ignoredErrors) {
this.ignoredErrors = ignoredErrors;
}

public @Nullable Boolean getSendClientReports() {
Expand Down
18 changes: 14 additions & 4 deletions sentry/src/main/java/io/sentry/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,7 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul
if (event != null) {
final Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null
&& ExceptionUtils.isIgnored(
options.getIgnoredExceptionsForType(),
options.getIgnoredExceptions(),
eventThrowable)) {
&& ExceptionUtils.isIgnored(options.getIgnoredExceptionsForType(), eventThrowable)) {
options
.getLogger()
.log(
Expand All @@ -114,6 +111,19 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
return SentryId.EMPTY_ID;
}

if (ErrorUtils.isIgnored(options.getIgnoredErrors(), event)) {
options
.getLogger()
.log(
SentryLevel.DEBUG,
"Event was dropped as the error %s is ignored",
event.getMessage());
options
.getClientReportRecorder()
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
return SentryId.EMPTY_ID;
}
}

if (shouldApplyScopeData(event, hint)) {
Expand Down
34 changes: 17 additions & 17 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ public class SentryOptions {
new CopyOnWriteArraySet<>();

/**
* Exception names or regex patterns that the captured exception will be tested against. If there
* is a match, the captured exception will not be sent to Sentry as {@link SentryEvent}.
* Strings or regex patterns that possible error messages for an event will be tested against. If
* there is a match, the captured event will not be sent to Sentry.
*/
private @Nullable List<FilterString> ignoredExceptions = null;
private @Nullable List<FilterString> ignoredErrors = null;

/**
* Code that provides middlewares, bindings or hooks into certain frameworks or environments,
Expand Down Expand Up @@ -1578,30 +1578,30 @@ boolean containsIgnoredExceptionForType(final @NotNull Throwable throwable) {
return this.ignoredExceptionsForType.contains(throwable.getClass());
}

public @Nullable List<FilterString> getIgnoredExceptions() {
return ignoredExceptions;
public @Nullable List<FilterString> getIgnoredErrors() {
return ignoredErrors;
}

public void setIgnoredExceptions(final @Nullable List<String> ignoredExceptions) {
if (ignoredExceptions == null) {
this.ignoredExceptions = null;
public void setIgnoredErrors(final @Nullable List<String> ignoredErrors) {
if (ignoredErrors == null) {
this.ignoredErrors = null;
} else {
@NotNull final List<FilterString> patterns = new ArrayList<>();
for (String pattern : ignoredExceptions) {
for (String pattern : ignoredErrors) {
if (pattern != null && !pattern.isEmpty()) {
patterns.add(new FilterString(pattern));
}
}

this.ignoredExceptions = patterns;
this.ignoredErrors = patterns;
}
}

public void addIgnoredException(final @NotNull String pattern) {
if (ignoredExceptions == null) {
ignoredExceptions = new ArrayList<>();
public void addIgnoredError(final @NotNull String pattern) {
if (ignoredErrors == null) {
ignoredErrors = new ArrayList<>();
}
ignoredExceptions.add(new FilterString(pattern));
ignoredErrors.add(new FilterString(pattern));
}

/**
Expand Down Expand Up @@ -2833,9 +2833,9 @@ public void merge(final @NotNull ExternalOptions options) {
final List<String> ignoredTransactions = new ArrayList<>(options.getIgnoredTransactions());
setIgnoredTransactions(ignoredTransactions);
}
if (options.getIgnoredExceptions() != null) {
final List<String> ignoredExceptions = new ArrayList<>(options.getIgnoredExceptions());
setIgnoredExceptions(ignoredExceptions);
if (options.getIgnoredErrors() != null) {
final List<String> ignoredExceptions = new ArrayList<>(options.getIgnoredErrors());
setIgnoredErrors(ignoredExceptions);
}
if (options.isEnableBackpressureHandling() != null) {
setEnableBackpressureHandling(options.isEnableBackpressureHandling());
Expand Down
69 changes: 69 additions & 0 deletions sentry/src/main/java/io/sentry/util/ErrorUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.sentry.util;

import io.sentry.FilterString;
import io.sentry.SentryEvent;
import io.sentry.protocol.Message;
import io.sentry.protocol.SentryException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class ErrorUtils {

/** Checks if an error has been ignored. */
@ApiStatus.Internal
public static boolean isIgnored(
final @Nullable List<FilterString> ignoredErrors, final @NotNull SentryEvent event) {
if (event == null || ignoredErrors == null || ignoredErrors.isEmpty()) {
return false;
}

final @NotNull Set<String> possibleMessages = new HashSet<>();

final @Nullable Message eventMessage = event.getMessage();
if (eventMessage != null) {
final @Nullable String stringMessage = eventMessage.getMessage();
if (stringMessage != null) {
possibleMessages.add(stringMessage);
}
final @Nullable String formattedMessage = eventMessage.getFormatted();
if (formattedMessage != null) {
possibleMessages.add(formattedMessage);
}
}
final @Nullable List<SentryException> exceptions = event.getExceptions();
if (exceptions != null && !exceptions.isEmpty()) {
for (final @Nullable SentryException exception : exceptions) {
if (exception != null) {
final @Nullable String value = exception.getValue();
if (value != null) {
possibleMessages.add(value);
}
}
}
}
final @Nullable Throwable throwable = event.getThrowable();
if (throwable != null) {
possibleMessages.add(throwable.toString());
}

for (final @NotNull FilterString filter : ignoredErrors) {
if (possibleMessages.contains(filter.getFilterString())) {
return true;
}
}

for (final @NotNull FilterString filter : ignoredErrors) {
for (final @NotNull String message : possibleMessages) {
if (filter.matches(message)) {
return true;
}
}
}

return false;
}
}
37 changes: 2 additions & 35 deletions sentry/src/main/java/io/sentry/util/ExceptionUtils.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package io.sentry.util;

import io.sentry.FilterString;
import java.util.List;
import java.util.Set;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
public final class ExceptionUtils {
Expand All @@ -27,39 +24,9 @@ public final class ExceptionUtils {

/** Checks if an exception has been ignored. */
@ApiStatus.Internal
public static @NotNull boolean isIgnored(
public static boolean isIgnored(
final @NotNull Set<Class<? extends Throwable>> ignoredExceptionsForType,
final @Nullable List<FilterString> ignoredExceptions,
final @NotNull Throwable throwable) {
if (throwable == null) {
return false;
}

final Class<? extends Throwable> throwableClass = throwable.getClass();
if (ignoredExceptionsForType.contains(throwableClass)) {
return true;
}

if (ignoredExceptions == null || ignoredExceptions.isEmpty()) {
return false;
}
final String throwableClassName = throwableClass.getCanonicalName();
if (throwableClassName == null) {
return false;
}

for (final FilterString filter : ignoredExceptions) {
if (filter.getFilterString().equals(throwableClassName)) {
return true;
}
}

for (final FilterString filter : ignoredExceptions) {
if (filter.matches(throwableClassName)) {
return true;
}
}

return false;
return ignoredExceptionsForType.contains(throwable.getClass());
}
}
Loading

0 comments on commit 6e78fd0

Please sign in to comment.