Skip to content

Commit d0a8b22

Browse files
committed
convert away from blob
1 parent 859b52c commit d0a8b22

6 files changed

Lines changed: 42 additions & 86 deletions

File tree

bugsnag/src/main/java/com/bugsnag/Configuration.java

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,11 @@ public String[] getDiscardClasses() {
263263

264264
/**
265265
* Set which exception classes should be ignored (not sent) by Bugsnag.
266-
* Supports glob-style wildcards: * (matches any characters, including package
267-
* separators '.') and ? (matches a single character).
266+
* Supports Java regex patterns for matching exception class names.
267+
* For exact matches, use the fully qualified class name without regex metacharacters.
268+
* For pattern matching, use standard Java regex syntax (e.g., "java\\.io\\..*" to match all java.io exceptions).
268269
*
269-
* @param discardClasses a list of exception class patterns to ignore
270+
* @param discardClasses a list of exception class name patterns (regex) to ignore
270271
*/
271272
public void setDiscardClasses(String[] discardClasses) {
272273
this.discardClassRegexPatterns.clear();
@@ -276,62 +277,13 @@ public void setDiscardClasses(String[] discardClasses) {
276277
if (pattern != null && !pattern.isEmpty()) {
277278
// Store original pattern string
278279
this.discardClassStringPatterns.add(pattern);
279-
// Convert glob-style wildcards to regex
280-
String regex = convertToRegex(pattern);
281-
this.discardClassRegexPatterns.add(Pattern.compile(regex));
280+
// Compile as regex pattern
281+
this.discardClassRegexPatterns.add(Pattern.compile(pattern));
282282
}
283283
}
284284
}
285285
}
286286

287-
/**
288-
* Converts a glob-style pattern to a regex pattern.
289-
* Supports * (matches any characters) and ? (matches single character).
290-
* If the pattern doesn't contain wildcards, it's treated as an exact match.
291-
*
292-
* @param pattern the glob-style pattern
293-
* @return the regex pattern
294-
*/
295-
private String convertToRegex(String pattern) {
296-
// If the pattern doesn't contain wildcards, match exactly
297-
if (!pattern.contains("*") && !pattern.contains("?")) {
298-
return Pattern.quote(pattern);
299-
}
300-
301-
StringBuilder regex = new StringBuilder();
302-
for (int i = 0; i < pattern.length(); i++) {
303-
char ch = pattern.charAt(i);
304-
switch (ch) {
305-
case '*':
306-
regex.append(".*");
307-
break;
308-
case '?':
309-
regex.append(".");
310-
break;
311-
case '.':
312-
case '(':
313-
case ')':
314-
case '+':
315-
case '|':
316-
case '^':
317-
case '$':
318-
case '@':
319-
case '%':
320-
case '[':
321-
case ']':
322-
case '{':
323-
case '}':
324-
case '\\':
325-
regex.append('\\').append(ch);
326-
break;
327-
default:
328-
regex.append(ch);
329-
break;
330-
}
331-
}
332-
return regex.toString();
333-
}
334-
335287
public Set<String> getEnabledReleaseStages() {
336288
return enabledReleaseStages;
337289
}

bugsnag/src/test/java/com/bugsnag/BugsnagTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.HashMap;
2424
import java.util.Map;
2525
import java.util.Set;
26+
import java.util.regex.Pattern;
2627

2728
public class BugsnagTest {
2829

@@ -61,13 +62,16 @@ public void testIgnoreClasses() {
6162
assertTrue(bugsnag.notify(new RuntimeException()));
6263
assertTrue(bugsnag.notify(new TestException()));
6364

64-
// Ignore just RuntimeException
65-
bugsnag.setDiscardClasses(RuntimeException.class.getName());
65+
// Ignore just RuntimeException (escape dots for regex)
66+
bugsnag.setDiscardClasses(Pattern.quote(RuntimeException.class.getName()));
6667
assertFalse(bugsnag.notify(new RuntimeException()));
6768
assertTrue(bugsnag.notify(new TestException()));
6869

69-
// Ignore both
70-
bugsnag.setDiscardClasses(RuntimeException.class.getName(), TestException.class.getName());
70+
// Ignore both (escape special regex characters)
71+
bugsnag.setDiscardClasses(
72+
Pattern.quote(RuntimeException.class.getName()),
73+
Pattern.quote(TestException.class.getName())
74+
);
7175
assertFalse(bugsnag.notify(new RuntimeException()));
7276
assertFalse(bugsnag.notify(new TestException()));
7377
}

bugsnag/src/test/java/com/bugsnag/ConfigurationDiscardClassesTest.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import org.junit.Test;
99

1010
/**
11-
* Test for Configuration.shouldIgnoreClass with pattern matching
11+
* Test for Configuration.shouldIgnoreClass with regex pattern matching
1212
*/
1313
public class ConfigurationDiscardClassesTest {
1414

@@ -29,7 +29,7 @@ public void testExactMatch() {
2929

3030
@Test
3131
public void testWildcardMatch() {
32-
config.setDiscardClasses(new String[] {"com.example.*"});
32+
config.setDiscardClasses(new String[] {"com\\.example\\..*"});
3333

3434
assertTrue(config.shouldIgnoreClass("com.example.CustomException"));
3535
assertTrue(config.shouldIgnoreClass("com.example.OtherException"));
@@ -39,7 +39,7 @@ public void testWildcardMatch() {
3939

4040
@Test
4141
public void testMultipleWildcards() {
42-
config.setDiscardClasses(new String[] {"com.*.Exception"});
42+
config.setDiscardClasses(new String[] {"com\\..*\\.Exception"});
4343

4444
assertTrue(config.shouldIgnoreClass("com.example.Exception"));
4545
assertTrue(config.shouldIgnoreClass("com.other.Exception"));
@@ -48,7 +48,7 @@ public void testMultipleWildcards() {
4848

4949
@Test
5050
public void testQuestionMarkWildcard() {
51-
config.setDiscardClasses(new String[] {"com.example.Exception?"});
51+
config.setDiscardClasses(new String[] {"com\\.example\\.Exception."});
5252

5353
assertTrue(config.shouldIgnoreClass("com.example.Exception1"));
5454
assertTrue(config.shouldIgnoreClass("com.example.ExceptionX"));
@@ -59,9 +59,9 @@ public void testQuestionMarkWildcard() {
5959
@Test
6060
public void testMultiplePatterns() {
6161
config.setDiscardClasses(new String[] {
62-
"java.io.*",
63-
"com.example.CustomException",
64-
"org.*.SpecialException"
62+
"java\\.io\\..*",
63+
"com\\.example\\.CustomException",
64+
"org\\..*\\.SpecialException"
6565
});
6666

6767
assertTrue(config.shouldIgnoreClass("java.io.IOException"));
@@ -74,7 +74,7 @@ public void testMultiplePatterns() {
7474

7575
@Test
7676
public void testGetDiscardClassesReturnsOriginalPatterns() {
77-
String[] patterns = new String[] {"com.example.*", "java.io.IOException"};
77+
String[] patterns = new String[] {"com\\.example\\..*", "java\\.io\\.IOException"};
7878
config.setDiscardClasses(patterns);
7979

8080
String[] retrieved = config.getDiscardClasses();
@@ -84,10 +84,10 @@ public void testGetDiscardClassesReturnsOriginalPatterns() {
8484
boolean hasWildcard = false;
8585
boolean hasExact = false;
8686
for (String pattern : retrieved) {
87-
if (pattern.equals("com.example.*")) {
87+
if (pattern.equals("com\\.example\\..*")) {
8888
hasWildcard = true;
8989
}
90-
if (pattern.equals("java.io.IOException")) {
90+
if (pattern.equals("java\\.io\\.IOException")) {
9191
hasExact = true;
9292
}
9393
}
@@ -106,7 +106,8 @@ public void testEmptyAndNullPatterns() {
106106

107107
@Test
108108
public void testSpecialCharactersAreEscaped() {
109-
config.setDiscardClasses(new String[] {"com.example.Exception$Inner"});
109+
// In regex, $ is a special character (end of line), so it needs to be escaped
110+
config.setDiscardClasses(new String[] {"com\\.example\\.Exception\\$Inner"});
110111

111112
assertTrue(config.shouldIgnoreClass("com.example.Exception$Inner"));
112113
assertFalse(config.shouldIgnoreClass("com.example.ExceptionXInner"));

features/fixtures/logback/ignored_class_wildcard_config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<releaseStage>production</releaseStage>
88
<appVersion>1.0.0</appVersion>
99

10-
<discardClass>java.lang.*</discardClass>
10+
<discardClass>java\.lang\..*</discardClass>
1111

1212
<endpoint>http://localhost:9339/notify</endpoint>
1313
</appender>

features/fixtures/scenarios/src/main/java/com/bugsnag/mazerunner/scenarios/IgnoredExceptionWildcardScenario.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.bugsnag.Bugsnag;
44

55
/**
6-
* Attempts to send ignored handled exceptions using wildcard patterns to Bugsnag,
6+
* Attempts to send ignored handled exceptions using regex patterns to Bugsnag,
77
* which should not result in any operation.
88
*/
99
public class IgnoredExceptionWildcardScenario extends Scenario {
@@ -14,15 +14,15 @@ public IgnoredExceptionWildcardScenario(Bugsnag bugsnag) {
1414

1515
@Override
1616
public void run() {
17-
// Use wildcard pattern to ignore all RuntimeException and its subclasses
18-
bugsnag.setDiscardClasses("java.lang.*");
17+
// Use regex pattern to ignore all java.lang exceptions
18+
bugsnag.setDiscardClasses("java\\.lang\\..*");
1919

20-
// These should all be ignored due to the wildcard pattern
20+
// These should all be ignored due to the regex pattern
2121
bugsnag.notify(new RuntimeException("Should never appear"));
2222
bugsnag.notify(new IllegalArgumentException("Should never appear"));
2323
bugsnag.notify(new IllegalStateException("Should never appear"));
24-
25-
// This is also ignored due to the wildcard pattern
24+
25+
// This is also ignored due to the regex pattern
2626
try {
2727
throw new NullPointerException("Should never appear");
2828
} catch (Exception e) {

features/fixtures/scenarios/src/main/java/com/bugsnag/mazerunner/scenarios/MultipleWildcardPatternsScenario.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import com.bugsnag.Bugsnag;
44

55
/**
6-
* Tests multiple wildcard patterns working together.
7-
* Uses both * and ? wildcards along with exact matches.
6+
* Tests multiple regex patterns working together.
87
*/
98
public class MultipleWildcardPatternsScenario extends Scenario {
109

@@ -14,19 +13,19 @@ public MultipleWildcardPatternsScenario(Bugsnag bugsnag) {
1413

1514
@Override
1615
public void run() {
17-
// Set multiple patterns: wildcards and exact matches
16+
// Set multiple regex patterns: matching specific packages and classes
1817
bugsnag.setDiscardClasses(
19-
"java.io.*", // All java.io exceptions
20-
"java.lang.IllegalStateException", // Exact match
21-
"java.lang.Illegal*" // All IllegalXException classes
18+
"java\\.io\\..*", // All java.io exceptions
19+
"java\\.lang\\.IllegalStateException", // Exact match
20+
"java\\.lang\\.Illegal.*" // All IllegalXException classes
2221
);
2322

2423
// These should all be ignored
25-
bugsnag.notify(new java.io.IOException("Should be ignored - java.io.*"));
26-
bugsnag.notify(new java.io.FileNotFoundException("Should be ignored - java.io.*"));
24+
bugsnag.notify(new java.io.IOException("Should be ignored - java\\.io\\..*"));
25+
bugsnag.notify(new java.io.FileNotFoundException("Should be ignored - java\\.io\\..*"));
2726
bugsnag.notify(new IllegalStateException("Should be ignored - exact match"));
28-
bugsnag.notify(new IllegalArgumentException("Should be ignored - java.lang.Illegal*"));
29-
27+
bugsnag.notify(new IllegalArgumentException("Should be ignored - java\\.lang\\.Illegal.*"));
28+
3029
// This should be sent (not matching any pattern)
3130
bugsnag.notify(new RuntimeException("Should be sent"));
3231
}

0 commit comments

Comments
 (0)