Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions core/src/main/java/dev/faststats/ErrorHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private static JsonObject compileAll(final TrackedError trackedError, @Nullable
@Nullable final Attributes defaultAttributes) {
final var error = trackedError.error();
final var report = new JsonObject();
final var message = getAnonymizedMessage(error, customPatterns);
final var message = anonymize(error.getMessage(), customPatterns);

final var stacktrace = new JsonArray();
final var header = message != null
Expand All @@ -54,7 +54,8 @@ private static JsonObject compileAll(final TrackedError trackedError, @Nullable
appendCauseChain(error.getCause(), stack, suppress, stacktrace, customPatterns);

report.addProperty("error", error.getClass().getName());
if (message != null) report.addProperty("message", message);
final var first = anonymize(findFirstMessage(error, null), customPatterns);
if (first != null) report.addProperty("message", first);

report.add("stack", stacktrace);
report.addProperty("handled", trackedError.handled());
Expand All @@ -75,7 +76,7 @@ private static void appendCauseChain(@Nullable Throwable cause, final List<Strin
if (suppress != null) toSuppress.addAll(suppress);
final var visited = Collections.<Throwable>newSetFromMap(new IdentityHashMap<>());
while (cause != null && visited.add(cause)) {
final var causeMessage = getAnonymizedMessage(cause, customPatterns);
final var causeMessage = anonymize(cause.getMessage(), customPatterns);
final var header = causeMessage != null
? "Caused by: " + cause.getClass().getName() + ": " + causeMessage
: "Caused by: " + cause.getClass().getName();
Expand Down Expand Up @@ -213,8 +214,16 @@ private static boolean isSameClassLoader(final ClassLoader classLoader, final Cl
return loader == current;
}

private static @Nullable String getAnonymizedMessage(final Throwable error, final List<Map.Entry<Pattern, String>> customPatterns) {
private static @Nullable String findFirstMessage(@Nullable final Throwable error, @Nullable Set<Throwable> visited) {
if (error == null) return null;
final var message = error.getMessage();
if (message != null) return message;
if (visited == null) visited = Collections.newSetFromMap(new IdentityHashMap<>());
if (!visited.add(error)) return null;
return findFirstMessage(error.getCause(), visited);
}

private static @Nullable String anonymize(@Nullable final String message, final List<Map.Entry<Pattern, String>> customPatterns) {
if (message == null) return null;
var truncated = message.length() > MAX_MESSAGE_LENGTH
? message.substring(0, MAX_MESSAGE_LENGTH) + "..."
Expand Down
12 changes: 12 additions & 0 deletions core/src/test/java/dev/faststats/ErrorTrackerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ public void nullMessagesAreNotSerializedAsMessageProperty() {
assertEquals("java.lang.RuntimeException", report.getAsJsonArray("stack").get(0).getAsString());
}

@Test
public void messageFallsBackToCauseMessage() {
final var cause = new IllegalArgumentException("cause message");
final var error = new RuntimeException(null, cause);

tracker.trackError(error);

final var report = tracker.getFullData().get(0).getAsJsonObject();
final var stack = report.getAsJsonArray("stack");
assertEquals("cause message", report.get("message").getAsString());
}

@Test
public void nestedCausesAreSerializedInOrder() {
final var root = new IllegalArgumentException("root secret 172.16.0.9");
Expand Down
Loading