Skip to content

Commit 82b9faf

Browse files
committed
address comments, add tests, add entry to CHANGELOG.md
1 parent c2a20cb commit 82b9faf

File tree

8 files changed

+85
-45
lines changed

8 files changed

+85
-45
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- Add `options.ignoreExceptions` to filter out exceptions that match a certain String or Regex ([#4083](https://github.com/getsentry/sentry-java/pull/4083))
8+
- Can be set in `sentry.properties`, e.g. `ignored-exceptions=java.lang.RuntimeException,io.sentry..*`
9+
- Can be set in environment variables, e.g. `SENTRY_IGNORED_EXCEPTIONS=java.lang.RuntimeException,io.sentry..*`
10+
- For Spring Boot, it can be set in `application.properties`, e.g. `sentry.ignored-exceptions=java.lang.RuntimeException,io.sentry..*`
11+
12+
## 8.0.0
13+
14+
### Summary
15+
516
Version 8 of the Sentry Android/Java SDK brings a variety of features and fixes. The most notable changes are:
617

718
- `Hub` has been replaced by `Scopes`

sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class SentryAutoConfigurationTest {
174174
"sentry.enabled=false",
175175
"sentry.send-modules=false",
176176
"sentry.ignored-checkins=slug1,slugB",
177+
"sentry.ignored-exceptions=com.some.Exception,io.sentry..*",
177178
"sentry.ignored-transactions=transactionName1,transactionNameB",
178179
"sentry.enable-backpressure-handling=false",
179180
"sentry.enable-spotlight=true",
@@ -215,6 +216,7 @@ class SentryAutoConfigurationTest {
215216
assertThat(options.isEnabled).isEqualTo(false)
216217
assertThat(options.isSendModules).isEqualTo(false)
217218
assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB"))
219+
assertThat(options.ignoredExceptions).containsOnly(FilterString("com.some.Exception"), FilterString("io.sentry..*"))
218220
assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB"))
219221
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
220222
assertThat(options.isForceInit).isEqualTo(true)

sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class SentryAutoConfigurationTest {
173173
"sentry.enabled=false",
174174
"sentry.send-modules=false",
175175
"sentry.ignored-checkins=slug1,slugB",
176+
"sentry.ignored-exceptions=com.some.Exception,io.sentry..*",
176177
"sentry.ignored-transactions=transactionName1,transactionNameB",
177178
"sentry.enable-backpressure-handling=false",
178179
"sentry.enable-spotlight=true",
@@ -214,6 +215,7 @@ class SentryAutoConfigurationTest {
214215
assertThat(options.isEnabled).isEqualTo(false)
215216
assertThat(options.isSendModules).isEqualTo(false)
216217
assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB"))
218+
assertThat(options.ignoredExceptions).containsOnly(FilterString("com.some.Exception"), FilterString("io.sentry..*"))
217219
assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB"))
218220
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
219221
assertThat(options.isForceInit).isEqualTo(true)

sentry/api/sentry.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6061,6 +6061,7 @@ public final class io/sentry/util/EventProcessorUtils {
60616061
public final class io/sentry/util/ExceptionUtils {
60626062
public fun <init> ()V
60636063
public static fun findRootCause (Ljava/lang/Throwable;)Ljava/lang/Throwable;
6064+
public static fun isIgnored (Ljava/util/Set;Ljava/util/List;Ljava/lang/Throwable;)Z
60646065
}
60656066

60666067
public final class io/sentry/util/FileUtils {

sentry/src/main/java/io/sentry/ExternalOptions.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,7 @@ public final class ExternalOptions {
128128
}
129129
options.setIdleTimeout(propertiesProvider.getLongProperty("idle-timeout"));
130130

131-
for (final String pattern : propertiesProvider.getList("ignored-exceptions")) {
132-
options.addIgnoredException(pattern);
133-
}
131+
options.setIgnoredExceptions(propertiesProvider.getList("ignored-exceptions"));
134132

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

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@
1111
import io.sentry.protocol.SentryTransaction;
1212
import io.sentry.transport.ITransport;
1313
import io.sentry.transport.RateLimiter;
14-
import io.sentry.util.CheckInUtils;
15-
import io.sentry.util.HintUtils;
16-
import io.sentry.util.Objects;
17-
import io.sentry.util.Random;
18-
import io.sentry.util.SentryRandom;
19-
import io.sentry.util.TracingUtils;
14+
import io.sentry.util.*;
2015
import java.io.Closeable;
2116
import java.io.IOException;
2217
import java.util.ArrayList;
@@ -103,42 +98,21 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul
10398

10499
if (event != null) {
105100
final Throwable eventThrowable = event.getThrowable();
106-
if (eventThrowable != null) {
107-
if (options.containsIgnoredExceptionForType(eventThrowable)) {
108-
options
109-
.getLogger()
110-
.log(
111-
SentryLevel.DEBUG,
112-
"Event was dropped as the exception %s is ignored",
113-
eventThrowable.getClass());
114-
options
115-
.getClientReportRecorder()
116-
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
117-
return SentryId.EMPTY_ID;
118-
}
119-
120-
final List<FilterString> ignoredExceptions = options.getIgnoredExceptions();
121-
if (ignoredExceptions != null) {
122-
final String throwableClassName = eventThrowable.getClass().getCanonicalName();
123-
if (throwableClassName != null) {
124-
for (final FilterString filter : ignoredExceptions) {
125-
if (filter.getFilterString().equals(throwableClassName)
126-
|| filter.matches(throwableClassName)) {
127-
options
128-
.getLogger()
129-
.log(
130-
SentryLevel.DEBUG,
131-
"Event was dropped as the exception %s matches the ignoreExceptions filter pattern %s",
132-
throwableClassName,
133-
filter.getFilterString());
134-
options
135-
.getClientReportRecorder()
136-
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
137-
return SentryId.EMPTY_ID;
138-
}
139-
}
140-
}
141-
}
101+
if (eventThrowable != null
102+
&& ExceptionUtils.isIgnored(
103+
options.getIgnoredExceptionsForType(),
104+
options.getIgnoredExceptions(),
105+
eventThrowable)) {
106+
options
107+
.getLogger()
108+
.log(
109+
SentryLevel.DEBUG,
110+
"Event was dropped as the exception %s is ignored",
111+
eventThrowable.getClass());
112+
options
113+
.getClientReportRecorder()
114+
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
115+
return SentryId.EMPTY_ID;
142116
}
143117
}
144118

sentry/src/main/java/io/sentry/util/ExceptionUtils.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package io.sentry.util;
22

3+
import io.sentry.FilterString;
4+
import java.util.List;
5+
import java.util.Set;
36
import org.jetbrains.annotations.ApiStatus;
47
import org.jetbrains.annotations.NotNull;
8+
import org.jetbrains.annotations.Nullable;
59

610
@ApiStatus.Internal
711
public final class ExceptionUtils {
@@ -20,4 +24,42 @@ public final class ExceptionUtils {
2024
}
2125
return rootCause;
2226
}
27+
28+
/** Checks if an exception has been ignored. */
29+
@ApiStatus.Internal
30+
public static @NotNull boolean isIgnored(
31+
final @NotNull Set<Class<? extends Throwable>> ignoredExceptionsForType,
32+
final @Nullable List<FilterString> ignoredExceptions,
33+
final @NotNull Throwable throwable) {
34+
if (throwable == null) {
35+
return false;
36+
}
37+
38+
final Class<? extends Throwable> throwableClass = throwable.getClass();
39+
if (ignoredExceptionsForType.contains(throwableClass)) {
40+
return true;
41+
}
42+
43+
if (ignoredExceptions == null || ignoredExceptions.isEmpty()) {
44+
return false;
45+
}
46+
final String throwableClassName = throwableClass.getCanonicalName();
47+
if (throwableClassName == null) {
48+
return false;
49+
}
50+
51+
for (final FilterString filter : ignoredExceptions) {
52+
if (filter.getFilterString().equals(throwableClassName)) {
53+
return true;
54+
}
55+
}
56+
57+
for (final FilterString filter : ignoredExceptions) {
58+
if (filter.matches(throwableClassName)) {
59+
return true;
60+
}
61+
}
62+
63+
return false;
64+
}
2365
}

sentry/src/test/java/io/sentry/SentryClientTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.junit.rules.TemporaryFolder
3232
import org.mockito.kotlin.any
3333
import org.mockito.kotlin.anyOrNull
3434
import org.mockito.kotlin.argumentCaptor
35+
import org.mockito.kotlin.atLeast
3536
import org.mockito.kotlin.check
3637
import org.mockito.kotlin.doAnswer
3738
import org.mockito.kotlin.eq
@@ -1792,6 +1793,15 @@ class SentryClientTest {
17921793
verify(fixture.transport).send(any(), anyOrNull())
17931794
}
17941795

1796+
@Test
1797+
fun `when ignoredExceptionsForType and ignoredExceptions are not explicitly specified, capturing event sends exceptions`() {
1798+
val sut = fixture.getSut()
1799+
sut.captureException(IllegalStateException())
1800+
class MyException(message: String) : Exception(message)
1801+
sut.captureException(MyException("hello"))
1802+
verify(fixture.transport, atLeast(2)).send(any(), anyOrNull())
1803+
}
1804+
17951805
@Test
17961806
fun `screenshot is added to the envelope from the hint`() {
17971807
val sut = fixture.getSut()

0 commit comments

Comments
 (0)