Skip to content

Commit 990f7b2

Browse files
adinauerlbloder
andauthored
Implement local scope by adding overloads to the capture methods that accept a ScopeCallback (#2084)
* Add localScope to captureException, captureMessage in Hub.java and Sentry.java * add overloads with scope callback for captureEvent, add local scope methods to Sentry.java, adapt tests, use correct methods in HubAdapter * update sentry.api to reflect the new methods, run spotless, adapt test failing due to method overload ambiguity * change User facing api surface by making ScopeCallback not null, improve tests * add changelog * implement suggested change * add missing newLine in CHANGELOG, make Scope final * use correct PR number Co-authored-by: Lukas Bloder <[email protected]>
1 parent c62a9f7 commit 990f7b2

File tree

12 files changed

+415
-13
lines changed

12 files changed

+415
-13
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Implement local scope by adding overloads to the capture methods that accept a ScopeCallback ([#2084](https://github.com/getsentry/sentry-java/pull/2084))
8+
39
## 6.0.0
410

511
### Sentry Self-hosted Compatibility

sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.nhaarman.mockitokotlin2.mock
66
import com.nhaarman.mockitokotlin2.verify
77
import graphql.execution.DataFetcherExceptionHandler
88
import graphql.execution.DataFetcherExceptionHandlerParameters
9+
import io.sentry.Hint
910
import io.sentry.IHub
1011
import kotlin.test.Test
1112

@@ -21,7 +22,7 @@ class SentryDataFetcherExceptionHandlerTest {
2122
val parameters = DataFetcherExceptionHandlerParameters.newExceptionParameters().exception(exception).build()
2223
handler.onException(parameters)
2324

24-
verify(hub).captureException(eq(exception), anyOrNull())
25+
verify(hub).captureException(eq(exception), anyOrNull<Hint>())
2526
verify(delegate).onException(parameters)
2627
}
2728
}

sentry/api/sentry.api

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,11 @@ public final class io/sentry/Hub : io/sentry/IHub {
208208
public fun bindClient (Lio/sentry/ISentryClient;)V
209209
public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
210210
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
211+
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
211212
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
213+
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
212214
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
215+
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
213216
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceState;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId;
214217
public fun captureUserFeedback (Lio/sentry/UserFeedback;)V
215218
public fun clearBreadcrumbs ()V
@@ -248,8 +251,11 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
248251
public fun bindClient (Lio/sentry/ISentryClient;)V
249252
public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
250253
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
254+
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
251255
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
256+
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
252257
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
258+
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
253259
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceState;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId;
254260
public fun captureUserFeedback (Lio/sentry/UserFeedback;)V
255261
public fun clearBreadcrumbs ()V
@@ -303,10 +309,16 @@ public abstract interface class io/sentry/IHub {
303309
public abstract fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
304310
public fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId;
305311
public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
312+
public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
313+
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
306314
public fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId;
307315
public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
316+
public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
317+
public fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
308318
public fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId;
319+
public fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
309320
public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
321+
public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
310322
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
311323
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceState;)Lio/sentry/protocol/SentryId;
312324
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceState;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
@@ -539,8 +551,11 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
539551
public fun bindClient (Lio/sentry/ISentryClient;)V
540552
public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
541553
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
554+
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
542555
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
556+
public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
543557
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
558+
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
544559
public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceState;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId;
545560
public fun captureUserFeedback (Lio/sentry/UserFeedback;)V
546561
public fun clearBreadcrumbs ()V
@@ -842,10 +857,16 @@ public final class io/sentry/Sentry {
842857
public static fun bindClient (Lio/sentry/ISentryClient;)V
843858
public static fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId;
844859
public static fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
860+
public static fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
861+
public static fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
845862
public static fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId;
846863
public static fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
864+
public static fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
865+
public static fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
847866
public static fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId;
867+
public static fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
848868
public static fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
869+
public static fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId;
849870
public static fun captureUserFeedback (Lio/sentry/UserFeedback;)V
850871
public static fun clearBreadcrumbs ()V
851872
public static fun close ()V

sentry/src/main/java/io/sentry/Hub.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ public boolean isEnabled() {
7676
@Override
7777
public @NotNull SentryId captureEvent(
7878
final @NotNull SentryEvent event, final @Nullable Hint hint) {
79+
return captureEventInternal(event, hint, null);
80+
}
81+
82+
@Override
83+
public @NotNull SentryId captureEvent(
84+
final @NotNull SentryEvent event,
85+
final @Nullable Hint hint,
86+
final @NotNull ScopeCallback callback) {
87+
return captureEventInternal(event, hint, callback);
88+
}
89+
90+
private @NotNull SentryId captureEventInternal(
91+
final @NotNull SentryEvent event,
92+
final @Nullable Hint hint,
93+
final @Nullable ScopeCallback scopeCallback) {
7994
SentryId sentryId = SentryId.EMPTY_ID;
8095
if (!isEnabled()) {
8196
options
@@ -88,7 +103,10 @@ public boolean isEnabled() {
88103
try {
89104
assignTraceContext(event);
90105
final StackItem item = stack.peek();
91-
sentryId = item.getClient().captureEvent(event, item.getScope(), hint);
106+
107+
final Scope scope = buildLocalScope(item.getScope(), scopeCallback);
108+
109+
sentryId = item.getClient().captureEvent(event, scope, hint);
92110
this.lastEventId = sentryId;
93111
} catch (Throwable e) {
94112
options
@@ -103,6 +121,21 @@ public boolean isEnabled() {
103121
@Override
104122
public @NotNull SentryId captureMessage(
105123
final @NotNull String message, final @NotNull SentryLevel level) {
124+
return captureMessageInternal(message, level, null);
125+
}
126+
127+
@Override
128+
public @NotNull SentryId captureMessage(
129+
final @NotNull String message,
130+
final @NotNull SentryLevel level,
131+
final @NotNull ScopeCallback callback) {
132+
return captureMessageInternal(message, level, callback);
133+
}
134+
135+
private @NotNull SentryId captureMessageInternal(
136+
final @NotNull String message,
137+
final @NotNull SentryLevel level,
138+
final @Nullable ScopeCallback scopeCallback) {
106139
SentryId sentryId = SentryId.EMPTY_ID;
107140
if (!isEnabled()) {
108141
options
@@ -115,7 +148,10 @@ public boolean isEnabled() {
115148
} else {
116149
try {
117150
final StackItem item = stack.peek();
118-
sentryId = item.getClient().captureMessage(message, level, item.getScope());
151+
152+
final Scope scope = buildLocalScope(item.getScope(), scopeCallback);
153+
154+
sentryId = item.getClient().captureMessage(message, level, scope);
119155
} catch (Throwable e) {
120156
options.getLogger().log(SentryLevel.ERROR, "Error while capturing message: " + message, e);
121157
}
@@ -154,6 +190,22 @@ public boolean isEnabled() {
154190
@Override
155191
public @NotNull SentryId captureException(
156192
final @NotNull Throwable throwable, final @Nullable Hint hint) {
193+
return captureExceptionInternal(throwable, hint, null);
194+
}
195+
196+
@Override
197+
public @NotNull SentryId captureException(
198+
final @NotNull Throwable throwable,
199+
final @Nullable Hint hint,
200+
final @NotNull ScopeCallback callback) {
201+
202+
return captureExceptionInternal(throwable, hint, callback);
203+
}
204+
205+
private @NotNull SentryId captureExceptionInternal(
206+
final @NotNull Throwable throwable,
207+
final @Nullable Hint hint,
208+
final @Nullable ScopeCallback scopeCallback) {
157209
SentryId sentryId = SentryId.EMPTY_ID;
158210
if (!isEnabled()) {
159211
options
@@ -168,7 +220,10 @@ public boolean isEnabled() {
168220
final StackItem item = stack.peek();
169221
final SentryEvent event = new SentryEvent(throwable);
170222
assignTraceContext(event);
171-
sentryId = item.getClient().captureEvent(event, item.getScope(), hint);
223+
224+
final Scope scope = buildLocalScope(item.getScope(), scopeCallback);
225+
226+
sentryId = item.getClient().captureEvent(event, scope, hint);
172227
} catch (Throwable e) {
173228
options
174229
.getLogger()
@@ -761,4 +816,14 @@ SpanContext getSpanContext(final @NotNull Throwable throwable) {
761816
}
762817
return null;
763818
}
819+
820+
private Scope buildLocalScope(
821+
final @NotNull Scope scope, final @Nullable ScopeCallback callback) {
822+
if (callback != null) {
823+
final Scope localScope = new Scope(scope);
824+
callback.run(localScope);
825+
return localScope;
826+
}
827+
return scope;
828+
}
764829
}

sentry/src/main/java/io/sentry/HubAdapter.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,23 @@ public boolean isEnabled() {
2929
return Sentry.captureEvent(event, hint);
3030
}
3131

32+
@Override
33+
public @NotNull SentryId captureEvent(
34+
@NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) {
35+
return Sentry.captureEvent(event, hint, callback);
36+
}
37+
3238
@Override
3339
public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) {
3440
return Sentry.captureMessage(message, level);
3541
}
3642

43+
@Override
44+
public @NotNull SentryId captureMessage(
45+
@NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) {
46+
return Sentry.captureMessage(message, level, callback);
47+
}
48+
3749
@ApiStatus.Internal
3850
@Override
3951
public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) {
@@ -45,6 +57,12 @@ public boolean isEnabled() {
4557
return Sentry.captureException(throwable, hint);
4658
}
4759

60+
@Override
61+
public @NotNull SentryId captureException(
62+
@NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) {
63+
return Sentry.captureException(throwable, hint, callback);
64+
}
65+
4866
@Override
4967
public void captureUserFeedback(@NotNull UserFeedback userFeedback) {
5068
Sentry.captureUserFeedback(userFeedback);

sentry/src/main/java/io/sentry/IHub.java

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,35 @@ public interface IHub {
3636
* @return The Id (SentryId object) of the event
3737
*/
3838
default @NotNull SentryId captureEvent(@NotNull SentryEvent event) {
39-
return captureEvent(event, null);
39+
return captureEvent(event, new Hint());
4040
}
4141

42+
/**
43+
* Captures the event.
44+
*
45+
* @param event the event
46+
* @param callback The callback to configure the scope for a single invocation.
47+
* @return The Id (SentryId object) of the event
48+
*/
49+
default @NotNull SentryId captureEvent(
50+
@NotNull SentryEvent event, final @NotNull ScopeCallback callback) {
51+
return captureEvent(event, new Hint(), callback);
52+
}
53+
54+
/**
55+
* Captures the event.
56+
*
57+
* @param event the event
58+
* @param hint SDK specific but provides high level information about the origin of the event
59+
* @param callback The callback to configure the scope for a single invocation.
60+
* @return The Id (SentryId object) of the event
61+
*/
62+
@NotNull
63+
SentryId captureEvent(
64+
final @NotNull SentryEvent event,
65+
final @Nullable Hint hint,
66+
final @NotNull ScopeCallback callback);
67+
4268
/**
4369
* Captures the message.
4470
*
@@ -59,6 +85,30 @@ public interface IHub {
5985
@NotNull
6086
SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level);
6187

88+
/**
89+
* Captures the message.
90+
*
91+
* @param message The message to send.
92+
* @param level The message level.
93+
* @param callback The callback to configure the scope for a single invocation.
94+
* @return The Id (SentryId object) of the event
95+
*/
96+
@NotNull
97+
SentryId captureMessage(
98+
@NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback);
99+
100+
/**
101+
* Captures the message.
102+
*
103+
* @param message The message to send.
104+
* @param callback The callback to configure the scope for a single invocation.
105+
* @return The Id (SentryId object) of the event
106+
*/
107+
default @NotNull SentryId captureMessage(
108+
@NotNull String message, @NotNull ScopeCallback callback) {
109+
return captureMessage(message, SentryLevel.INFO, callback);
110+
}
111+
62112
/**
63113
* Captures an envelope.
64114
*
@@ -96,9 +146,35 @@ public interface IHub {
96146
* @return The Id (SentryId object) of the event
97147
*/
98148
default @NotNull SentryId captureException(@NotNull Throwable throwable) {
99-
return captureException(throwable, null);
149+
return captureException(throwable, new Hint());
100150
}
101151

152+
/**
153+
* Captures the exception.
154+
*
155+
* @param throwable The exception.
156+
* @param callback The callback to configure the scope for a single invocation.
157+
* @return The Id (SentryId object) of the event
158+
*/
159+
default @NotNull SentryId captureException(
160+
@NotNull Throwable throwable, final @NotNull ScopeCallback callback) {
161+
return captureException(throwable, new Hint(), callback);
162+
}
163+
164+
/**
165+
* Captures the exception.
166+
*
167+
* @param throwable The exception.
168+
* @param hint SDK specific but provides high level information about the origin of the event
169+
* @param callback The callback to configure the scope for a single invocation.
170+
* @return The Id (SentryId object) of the event
171+
*/
172+
@NotNull
173+
SentryId captureException(
174+
final @NotNull Throwable throwable,
175+
final @Nullable Hint hint,
176+
final @NotNull ScopeCallback callback);
177+
102178
/**
103179
* Captures a manually created user feedback and sends it to Sentry.
104180
*

sentry/src/main/java/io/sentry/NoOpHub.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,23 @@ public boolean isEnabled() {
3030
return SentryId.EMPTY_ID;
3131
}
3232

33+
@Override
34+
public @NotNull SentryId captureEvent(
35+
@NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) {
36+
return SentryId.EMPTY_ID;
37+
}
38+
3339
@Override
3440
public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) {
3541
return SentryId.EMPTY_ID;
3642
}
3743

44+
@Override
45+
public @NotNull SentryId captureMessage(
46+
@NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) {
47+
return SentryId.EMPTY_ID;
48+
}
49+
3850
@Override
3951
public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) {
4052
return SentryId.EMPTY_ID;
@@ -45,6 +57,12 @@ public boolean isEnabled() {
4557
return SentryId.EMPTY_ID;
4658
}
4759

60+
@Override
61+
public @NotNull SentryId captureException(
62+
@NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) {
63+
return SentryId.EMPTY_ID;
64+
}
65+
4866
@Override
4967
public void captureUserFeedback(@NotNull UserFeedback userFeedback) {}
5068

0 commit comments

Comments
 (0)