Skip to content

Commit d0c08e7

Browse files
authored
Fix ensure session is updated using configureScope (#2846)
1 parent beba014 commit d0c08e7

File tree

3 files changed

+64
-49
lines changed

3 files changed

+64
-49
lines changed

CHANGELOG.md

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

33
## Unreleased
44

5+
### Features
6+
- (Internal) Extend APIs for hybrid SDKs ([#2814](https://github.com/getsentry/sentry-java/pull/2814), [#2846](https://github.com/getsentry/sentry-java/pull/2846))
7+
58
### Fixes
69

710
- Fix ANRv2 thread dump parsing for native-only threads ([#2839](https://github.com/getsentry/sentry-java/pull/2839))

sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public final class InternalSentrySdk {
4141
@Nullable
4242
public static Scope getCurrentScope() {
4343
final @NotNull AtomicReference<Scope> scopeRef = new AtomicReference<>();
44-
HubAdapter.getInstance().withScope(scopeRef::set);
44+
//noinspection Convert2MethodRef
45+
HubAdapter.getInstance().withScope(scope -> scopeRef.set(scope));
4546
return scopeRef.get();
4647
}
4748

@@ -60,15 +61,14 @@ public static Map<String, Object> serializeScope(
6061
final @NotNull Context context,
6162
final @NotNull SentryAndroidOptions options,
6263
final @Nullable Scope scope) {
64+
6365
final @NotNull Map<String, Object> data = new HashMap<>();
6466
if (scope == null) {
6567
return data;
6668
}
67-
68-
final @NotNull ILogger logger = options.getLogger();
69-
final @NotNull ObjectWriter writer = new MapObjectWriter(data);
70-
7169
try {
70+
final @NotNull ILogger logger = options.getLogger();
71+
final @NotNull ObjectWriter writer = new MapObjectWriter(data);
7272

7373
final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options);
7474
final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(true, true);
@@ -114,7 +114,7 @@ public static Map<String, Object> serializeScope(
114114
writer.name("fingerprint").value(logger, scope.getFingerprint());
115115
writer.name("level").value(logger, scope.getLevel());
116116
writer.name("breadcrumbs").value(logger, scope.getBreadcrumbs());
117-
} catch (Exception e) {
117+
} catch (Throwable e) {
118118
options.getLogger().log(SentryLevel.ERROR, "Could not serialize scope.", e);
119119
return new HashMap<>();
120120
}
@@ -124,54 +124,62 @@ public static Map<String, Object> serializeScope(
124124

125125
/**
126126
* Captures the provided envelope. Compared to {@link IHub#captureEvent(SentryEvent)} this method
127-
* - will not enrich events with additional data (e.g. scope) - will not execute beforeSend: it's
128-
* up to the caller to take care of this - will not perform any sampling: it's up to the caller to
129-
* take care of this - will enrich the envelope with a Session updates is applicable
127+
* <br>
128+
* - will not enrich events with additional data (e.g. scope)<br>
129+
* - will not execute beforeSend: it's up to the caller to take care of this<br>
130+
* - will not perform any sampling: it's up to the caller to take care of this<br>
131+
* - will enrich the envelope with a Session update if applicable<br>
130132
*
131133
* @param envelopeData the serialized envelope data
132-
* @return The Id (SentryId object) of the event
133-
* @throws Exception In case the provided envelope could not be parsed / is invalid
134+
* @return The Id (SentryId object) of the event, or null in case the envelope could not be
135+
* captured
134136
*/
135-
public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) throws Exception {
137+
@Nullable
138+
public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) {
136139
final @NotNull IHub hub = HubAdapter.getInstance();
137140
final @NotNull SentryOptions options = hub.getOptions();
138141

139-
final @NotNull ISerializer serializer = options.getSerializer();
140-
final @Nullable SentryEnvelope envelope =
141-
options.getEnvelopeReader().read(new ByteArrayInputStream(envelopeData));
142-
if (envelope == null) {
143-
throw new IllegalArgumentException("Envelope could not be read");
144-
}
142+
try {
143+
final @NotNull ISerializer serializer = options.getSerializer();
144+
final @Nullable SentryEnvelope envelope =
145+
options.getEnvelopeReader().read(new ByteArrayInputStream(envelopeData));
146+
if (envelope == null) {
147+
return null;
148+
}
145149

146-
final @NotNull List<SentryEnvelopeItem> envelopeItems = new ArrayList<>();
150+
final @NotNull List<SentryEnvelopeItem> envelopeItems = new ArrayList<>();
147151

148-
// determine session state based on events inside envelope
149-
@Nullable Session.State status = null;
150-
boolean crashedOrErrored = false;
151-
for (SentryEnvelopeItem item : envelope.getItems()) {
152-
envelopeItems.add(item);
152+
// determine session state based on events inside envelope
153+
@Nullable Session.State status = null;
154+
boolean crashedOrErrored = false;
155+
for (SentryEnvelopeItem item : envelope.getItems()) {
156+
envelopeItems.add(item);
153157

154-
final SentryEvent event = item.getEvent(serializer);
155-
if (event != null) {
156-
if (event.isCrashed()) {
157-
status = Session.State.Crashed;
158-
}
159-
if (event.isCrashed() || event.isErrored()) {
160-
crashedOrErrored = true;
158+
final SentryEvent event = item.getEvent(serializer);
159+
if (event != null) {
160+
if (event.isCrashed()) {
161+
status = Session.State.Crashed;
162+
}
163+
if (event.isCrashed() || event.isErrored()) {
164+
crashedOrErrored = true;
165+
}
161166
}
162167
}
163-
}
164168

165-
// update session and add it to envelope if necessary
166-
final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored);
167-
if (session != null) {
168-
final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session);
169-
envelopeItems.add(sessionItem);
170-
}
169+
// update session and add it to envelope if necessary
170+
final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored);
171+
if (session != null) {
172+
final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session);
173+
envelopeItems.add(sessionItem);
174+
}
171175

172-
final SentryEnvelope repackagedEnvelope =
173-
new SentryEnvelope(envelope.getHeader(), envelopeItems);
174-
return hub.captureEnvelope(repackagedEnvelope);
176+
final SentryEnvelope repackagedEnvelope =
177+
new SentryEnvelope(envelope.getHeader(), envelopeItems);
178+
return hub.captureEnvelope(repackagedEnvelope);
179+
} catch (Throwable t) {
180+
options.getLogger().log(SentryLevel.ERROR, "Failed to capture envelope", t);
181+
}
182+
return null;
175183
}
176184

177185
@Nullable
@@ -181,7 +189,7 @@ private static Session updateSession(
181189
final @Nullable Session.State status,
182190
final boolean crashedOrErrored) {
183191
final @NotNull AtomicReference<Session> sessionRef = new AtomicReference<>();
184-
hub.withScope(
192+
hub.configureScope(
185193
scope -> {
186194
final @Nullable Session session = scope.getSession();
187195
if (session != null) {

sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ import org.mockito.kotlin.whenever
2929
import java.io.ByteArrayInputStream
3030
import java.io.ByteArrayOutputStream
3131
import java.io.InputStreamReader
32+
import java.util.concurrent.atomic.AtomicReference
3233
import kotlin.test.BeforeTest
3334
import kotlin.test.Test
3435
import kotlin.test.assertEquals
35-
import kotlin.test.assertFails
3636
import kotlin.test.assertNotNull
3737
import kotlin.test.assertNull
3838
import kotlin.test.assertTrue
@@ -203,9 +203,7 @@ class InternalSentrySdkTest {
203203

204204
@Test
205205
fun `captureEnvelope fails if payload is invalid`() {
206-
assertFails {
207-
InternalSentrySdk.captureEnvelope(ByteArray(8))
208-
}
206+
assertNull(InternalSentrySdk.captureEnvelope(ByteArray(8)))
209207
}
210208

211209
@Test
@@ -251,20 +249,26 @@ class InternalSentrySdkTest {
251249
}
252250
)
253251

254-
// then the session should be included
255252
val capturedEnvelope = fixture.capturedEnvelopes.first()
256253
val capturedEnvelopeItems = capturedEnvelope.items.toList()
257254

258-
// and it should contain the original event / attachment
255+
// then it should contain the original event + session
259256
assertEquals(2, capturedEnvelopeItems.size)
260257
assertEquals(SentryItemType.Event, capturedEnvelopeItems[0].header.type)
261258
assertEquals(SentryItemType.Session, capturedEnvelopeItems[1].header.type)
262259

260+
// and then the sent session should be marked as crashed
263261
val capturedSession = fixture.options.serializer.deserialize(
264262
InputStreamReader(ByteArrayInputStream(capturedEnvelopeItems[1].data)),
265263
Session::class.java
266264
)!!
267-
268265
assertEquals(Session.State.Crashed, capturedSession.status)
266+
267+
// and the local session should be marked as crashed too
268+
val scopeRef = AtomicReference<Scope>()
269+
Sentry.configureScope { scope ->
270+
scopeRef.set(scope)
271+
}
272+
assertEquals(Session.State.Crashed, scopeRef.get().session!!.status)
269273
}
270274
}

0 commit comments

Comments
 (0)