Skip to content
This repository was archived by the owner on Aug 30, 2023. It is now read-only.
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,6 @@ class AndroidSerializerTest {

private fun generateEmptySentryEvent(): SentryEvent {
return SentryEvent().apply {
setBreadcrumbs(null)
setTags(null)
setExtra(null)
fingerprint = null
contexts = null
}
}
Expand Down
4 changes: 4 additions & 0 deletions sentry-core/src/main/java/io/sentry/core/Scope.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public void setFingerprint(List<String> fingerprint) {
this.fingerprint = fingerprint;
}

public void addFingerprint(String fingerprint) {
this.fingerprint.add(fingerprint);
}

public List<Breadcrumb> getBreadcrumbs() {
return breadcrumbs;
}
Expand Down
42 changes: 42 additions & 0 deletions sentry-core/src/main/java/io/sentry/core/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import io.sentry.core.transport.AsyncConnection;
import io.sentry.core.util.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class SentryClient implements ISentryClient {
static final String SENTRY_PROTOCOL_VERSION = "7";
Expand Down Expand Up @@ -48,6 +51,45 @@ public SentryId captureEvent(SentryEvent event, @Nullable Scope scope) {
event.setEnvironment(options.getEnvironment());
}

if (scope != null) {
if (event.getTransaction() == null) {
event.setTransaction(scope.getTransaction());
}
if (event.getUser() == null) {
event.setUser(scope.getUser());
}
if (event.getFingerprint() == null) {
event.setFingerprint(scope.getFingerprint());
}
if (event.getBreadcrumbs() == null) {
event.setBreadcrumbs(new ArrayList<>(scope.getBreadcrumbs()));
} else {
event.getBreadcrumbs().addAll(scope.getBreadcrumbs());
}
if (event.getTags() == null) {
event.setTags(new HashMap<>(scope.getTags()));
} else {
for (Map.Entry<String, String> item : scope.getTags().entrySet()) {
if (!event.getTags().containsKey(item.getKey())) {
event.getTags().put(item.getKey(), item.getValue());
}
}
}
if (event.getExtra() == null) {
event.setExtra(new HashMap<>(scope.getExtra()));
} else {
for (Map.Entry<String, Object> item : scope.getExtra().entrySet()) {
if (!event.getExtra().containsKey(item.getKey())) {
event.getExtra().put(item.getKey(), item.getValue());
}
}
}
// Level from scope exceptionally take precedence over the event
if (scope.getLevel() != null) {
event.setLevel(scope.getLevel());
}
}

for (EventProcessor processor : options.getEventProcessors()) {
processor.process(event);
}
Expand Down
42 changes: 35 additions & 7 deletions sentry-core/src/main/java/io/sentry/core/SentryEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public class SentryEvent implements IUnknownPropertiesConsumer {
private Request request;
private SdkVersion sdk;
private Contexts contexts = new Contexts();
private List<String> fingerprint = new ArrayList<>();
private List<Breadcrumb> breadcrumbs = new ArrayList<>();
private Map<String, String> tags = new HashMap<>();
private Map<String, Object> extra = new HashMap<>();
private List<String> fingerprint;
private List<Breadcrumb> breadcrumbs;
private Map<String, String> tags;
private Map<String, Object> extra;
private Map<String, Object> unknown;

SentryEvent(SentryId eventId, Date timestamp) {
Expand Down Expand Up @@ -203,30 +203,58 @@ public void setFingerprint(List<String> fingerprint) {
this.fingerprint = fingerprint;
}

public void addFingerprint(String fingerprint) {
if (this.fingerprint == null) {
this.fingerprint = new ArrayList<>();
}
this.fingerprint.add(fingerprint);
}

public List<Breadcrumb> getBreadcrumbs() {
return breadcrumbs;
}

public void setBreadcrumbs(ArrayList<Breadcrumb> breadcrumbs) {
public void setBreadcrumbs(List<Breadcrumb> breadcrumbs) {
this.breadcrumbs = breadcrumbs;
}

public void addBreadcrumb(Breadcrumb breadcrumb) {
if (breadcrumbs == null) {
breadcrumbs = new ArrayList<>();
}
breadcrumbs.add(breadcrumb);
}

public Map<String, String> getTags() {
return tags;
}

public void setTags(HashMap<String, String> tags) {
public void setTags(Map<String, String> tags) {
this.tags = tags;
}

public void setTag(String key, String value) {
if (tags == null) {
tags = new HashMap<>();
}
tags.put(key, value);
}

public Map<String, Object> getExtra() {
return extra;
}

public void setExtra(HashMap<String, Object> extra) {
public void setExtra(Map<String, Object> extra) {
this.extra = extra;
}

public void setExtra(String key, Object value) {
if (extra == null) {
extra = new HashMap<>();
}
extra.put(key, value);
}

public Contexts getContexts() {
return contexts;
}
Expand Down
114 changes: 114 additions & 0 deletions sentry-core/src/test/java/io/sentry/core/SentryClientTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import io.sentry.core.protocol.User
import io.sentry.core.transport.AsyncConnection
import kotlin.test.Ignore
import kotlin.test.Test
Expand Down Expand Up @@ -156,4 +157,117 @@ class SentryClientTest {
sut.captureEvent(event)
assertEquals(expected, event.environment)
}

@Test
fun `when captureEvent with scope, event should have its data if not set`() {
val event = SentryEvent()
val scope = createScope()

val sut = fixture.getSut()

sut.captureEvent(event, scope)
assertEquals("message", event.breadcrumbs[0].message)
assertEquals("extra", event.extra["extra"])
assertEquals("tags", event.tags["tags"])
assertEquals("fp", event.fingerprint[0])
assertEquals("transaction", event.transaction)
assertEquals("id", event.user.id)
assertEquals(SentryLevel.FATAL, event.level)
}

@Test
fun `when captureEvent with scope, event data has priority over scope but level and it should append extras, tags and breadcrumbs`() {
val event = createEvent()

val scope = createScope()

val sut = fixture.getSut()

sut.captureEvent(event, scope)

// breadcrumbs are appending
assertEquals("eventMessage", event.breadcrumbs[0].message)
assertEquals("message", event.breadcrumbs[1].message)

// extras are appending
assertEquals("eventExtra", event.extra["eventExtra"])
assertEquals("extra", event.extra["extra"])

// tags are appending
assertEquals("eventTag", event.tags["eventTag"])
assertEquals("tags", event.tags["tags"])

// fingerprint is replaced
assertEquals("eventFp", event.fingerprint[0])
assertEquals(1, event.fingerprint.size)

assertEquals("eventTransaction", event.transaction)

assertEquals("eventId", event.user.id)

assertEquals(SentryLevel.FATAL, event.level)
}

@Test
fun `when captureEvent with scope, event extras and tags are only append if key is absent`() {
val event = createEvent()

val scope = createScope()
scope.setExtra("eventExtra", "extra")
scope.setTag("eventTag", "tags")

val sut = fixture.getSut()

sut.captureEvent(event, scope)

// extras are appending
assertEquals("eventExtra", event.extra["eventExtra"])

// tags are appending
assertEquals("eventTag", event.tags["eventTag"])
}

@Test
fun `when captureEvent with scope, event should have its level if set`() {
val event = SentryEvent()
event.level = SentryLevel.DEBUG
val scope = createScope()

val sut = fixture.getSut()

sut.captureEvent(event, scope)
assertEquals(SentryLevel.FATAL, event.level)
}

private fun createScope(): Scope {
return Scope().apply {
addBreadcrumb(Breadcrumb().apply {
message = "message"
})
setExtra("extra", "extra")
setTag("tags", "tags")
addFingerprint("fp")
transaction = "transaction"
level = SentryLevel.FATAL
user = User().apply {
id = "id"
}
}
}

private fun createEvent(): SentryEvent {
return SentryEvent().apply {
addBreadcrumb(Breadcrumb().apply {
message = "eventMessage"
})
setExtra("eventExtra", "eventExtra")
setTag("eventTag", "eventTag")
addFingerprint("eventFp")
transaction = "eventTransaction"
level = SentryLevel.DEBUG
user = User().apply {
id = "eventId"
}
}
}
}