Skip to content

Commit 8860c0b

Browse files
committed
feat: add exception middleware to allow dropping exceptions clientside
1 parent c15d461 commit 8860c0b

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/main/java/net/hollowcube/posthog/PostHogClient.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.gson.FieldNamingPolicy;
44
import com.google.gson.Gson;
55
import com.google.gson.GsonBuilder;
6+
import com.google.gson.JsonObject;
67
import org.jetbrains.annotations.Blocking;
78
import org.jetbrains.annotations.Contract;
89
import org.jetbrains.annotations.NotNull;
@@ -12,6 +13,8 @@
1213
import java.util.HashMap;
1314
import java.util.Map;
1415
import java.util.Objects;
16+
import java.util.function.BiFunction;
17+
import java.util.function.Consumer;
1518

1619
import static net.hollowcube.posthog.PostHogNames.*;
1720

@@ -368,6 +371,8 @@ final class Builder {
368371
private Duration featureFlagsPollingInterval = Duration.ofMinutes(5);
369372
private Duration featureFlagsRequestTimeout = Duration.ofSeconds(3);
370373

374+
private BiFunction<Throwable, JsonObject, Boolean> exceptionMiddleware = null;
375+
371376
private Gson gson = null; // Set on build if not overridden
372377

373378
private Builder(@NotNull String projectApiKey) {
@@ -440,6 +445,12 @@ private Builder(@NotNull String projectApiKey) {
440445
return this;
441446
}
442447

448+
@Contract(pure = true)
449+
public @NotNull Builder exceptionMiddleware(@NotNull BiFunction<Throwable, JsonObject, Boolean> exceptionMiddleware) {
450+
this.exceptionMiddleware = Objects.requireNonNull(exceptionMiddleware);
451+
return this;
452+
}
453+
443454
/**
444455
* Allows overriding the {@link Gson} instance used for de/serializing events.
445456
* Can be useful for handling custom types.
@@ -465,7 +476,8 @@ private Builder(@NotNull String projectApiKey) {
465476
flushInterval, maxBatchSize, defaultEventProperties, // Events
466477
eventBatchTimeout,
467478
allowRemoteFeatureFlagEvaluation, sendFeatureFlagEvents, // Feature flags
468-
featureFlagsPollingInterval, featureFlagsRequestTimeout
479+
featureFlagsPollingInterval, featureFlagsRequestTimeout,
480+
exceptionMiddleware // Exceptions
469481
);
470482
}
471483
}

src/main/java/net/hollowcube/posthog/PostHogClientImpl.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Objects;
2020
import java.util.UUID;
2121
import java.util.concurrent.ConcurrentHashMap;
22+
import java.util.function.BiFunction;
2223

2324
import static net.hollowcube.posthog.FeatureFlagEvaluator.evaluateFeatureFlag;
2425
import static net.hollowcube.posthog.FeatureFlagState.REMOTE_EVAL_NOT_ALLOWED;
@@ -50,6 +51,8 @@ public final class PostHogClientImpl implements PostHogClient {
5051
private final boolean sendFeatureFlagEvents;
5152
private final Duration featureFlagsRequestTimeout;
5253

54+
private final BiFunction<Throwable, JsonObject, Boolean> exceptionMiddleware;
55+
5356
PostHogClientImpl(
5457
@NotNull Gson gson,
5558

@@ -65,7 +68,8 @@ public final class PostHogClientImpl implements PostHogClient {
6568
boolean allowRemoteFeatureFlagEvaluation,
6669
boolean sendFeatureFlagEvents,
6770
@NotNull Duration featureFlagsPollingInterval,
68-
@NotNull Duration featureFlagsRequestTimeout
71+
@NotNull Duration featureFlagsRequestTimeout,
72+
@Nullable BiFunction<Throwable, JsonObject, Boolean> exceptionMiddleware
6973
) {
7074
this.queue = new EventQueue(this::sendEventBatch, flushInterval, maxBatchSize);
7175
this.gson = gson;
@@ -88,6 +92,8 @@ public final class PostHogClientImpl implements PostHogClient {
8892
this.allowRemoteFeatureFlagEvaluation = allowRemoteFeatureFlagEvaluation;
8993
this.sendFeatureFlagEvents = sendFeatureFlagEvents;
9094
this.featureFlagsRequestTimeout = featureFlagsRequestTimeout;
95+
96+
this.exceptionMiddleware = exceptionMiddleware;
9197
}
9298

9399
@Override
@@ -345,7 +351,6 @@ private boolean trackCapturedFeatureFlagCall(@NotNull String distinctId, @NotNul
345351

346352
// Exceptions
347353

348-
349354
@Override
350355
public void captureException(@NotNull Throwable throwable, @Nullable String distinctId, @Nullable Object properties) {
351356
// this function shouldn't ever throw an error, so it logs exceptions instead of allowing them to propagate.
@@ -367,6 +372,9 @@ public void captureException(@NotNull Throwable throwable, @Nullable String dist
367372
eventProps.addProperty(EXCEPTION_PERSON_URL, String.format("%s/project/%s/person/%s",
368373
endpoint, projectApiKey, distinctId));
369374

375+
if (exceptionMiddleware != null && !exceptionMiddleware.apply(throwable, eventProps))
376+
return;
377+
370378
capture(distinctId, EXCEPTION, eventProps);
371379
} catch (Exception e) {
372380
log.error("failed to capture exception", e);
@@ -426,7 +434,7 @@ public void captureException(@NotNull Throwable throwable, @Nullable String dist
426434
// We lie and tell PostHog that this is a Python exception because they don't actually support
427435
// Java yet :) As far as i can tell this is only actually used for syntax highlighting in source
428436
// code (which we don't send) so this is probably OK for now.
429-
frame.addProperty("platform", "python");
437+
frame.addProperty("platform", "java");
430438
frame.addProperty("filename", element.getFileName());
431439
frame.addProperty("abs_path", element.getFileName());
432440

0 commit comments

Comments
 (0)