Skip to content

Commit fc6a314

Browse files
authored
fix: respect event data when applying/merging scope data (#1253)
1 parent 1fe9121 commit fc6a314

File tree

6 files changed

+141
-3
lines changed

6 files changed

+141
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
**Breaking changes**:
66

77
- Limiting the proguard rules in the NDK package moves the burden of the configuration to its users. Please ensure to [configure proguard](http://proguard.sourceforge.net/manual/examples.html#native) in your project so native methods in your namespace can be symbolicated if they appear in stack traces. ([#1250](https://github.com/getsentry/sentry-native/pull/1250))
8+
- When tags, contexts, and extra data are applied to events, the event data now takes precedence over the scope data as outlined in the [Hub & Scope Refactoring](https://develop.sentry.dev/sdk/miscellaneous/hub_and_scope_refactoring/#how-is-scope-data-applied-to-events) developer document and the linked RFC [code example](https://github.com/getsentry/rfcs/blob/fn/merge-hub-scope/text/0122-sdk-hub-scope-merge.md#applying-scopes). ([#1253](https://github.com/getsentry/sentry-native/pull/1253))
89

910
**Features**:
1011

@@ -14,6 +15,7 @@
1415

1516
- Reduce the scope of the proguard rules in the NDK package to local namespaces. ([#1250](https://github.com/getsentry/sentry-native/pull/1250))
1617
- Close the file and return 0 on success when writing raw envelopes. ([#1260](https://github.com/getsentry/sentry-native/pull/1260))
18+
- Fix event tags, contexts, and extra data to take precedence when applying scope data. ([#1253](https://github.com/getsentry/sentry-native/pull/1253))
1719

1820
**Docs**:
1921

src/sentry_value.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ sentry__value_merge_objects(sentry_value_t dst, sentry_value_t src)
977977
if (sentry__value_merge_objects(dst_val, src_val) != 0) {
978978
return 1;
979979
}
980-
} else {
980+
} else if (sentry_value_is_null(dst_val)) {
981981
if (sentry_value_set_by_key(dst, key, src_val) != 0) {
982982
return 1;
983983
}

tests/unit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_executable(sentry_test_unit
3535
test_path.c
3636
test_ratelimiter.c
3737
test_sampling.c
38+
test_scope.c
3839
test_session.c
3940
test_slice.c
4041
test_symbolizer.c

tests/unit/test_scope.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include "sentry.h"
2+
#include "sentry_scope.h"
3+
#include "sentry_testsupport.h"
4+
5+
SENTRY_TEST(scope_contexts)
6+
{
7+
SENTRY_TEST_OPTIONS_NEW(options);
8+
sentry_init(options);
9+
10+
#define TEST_CHECK_CONTEXT_EQUAL(event, key, value) \
11+
do { \
12+
sentry_value_t contexts = sentry_value_get_by_key(event, "contexts"); \
13+
TEST_CHECK_STRING_EQUAL( \
14+
sentry_value_as_string(sentry_value_get_by_key(contexts, key)), \
15+
value); \
16+
} while (0)
17+
18+
// scope: {"both":"scope","scope":"scope"}
19+
sentry_set_context("both", sentry_value_new_string("scope"));
20+
sentry_set_context("scope", sentry_value_new_string("scope"));
21+
22+
SENTRY_WITH_SCOPE (scope) {
23+
// event: {"both":"event","event":"event"}
24+
sentry_value_t event = sentry_value_new_object();
25+
{
26+
sentry_value_t contexts = sentry_value_new_object();
27+
sentry_value_set_by_key(
28+
contexts, "both", sentry_value_new_string("event"));
29+
sentry_value_set_by_key(
30+
contexts, "event", sentry_value_new_string("event"));
31+
sentry_value_set_by_key(event, "contexts", contexts);
32+
}
33+
34+
// event <- scope: {"both":"event","event":"event","scope":"scope"}
35+
sentry__scope_apply_to_event(scope, options, event, SENTRY_SCOPE_NONE);
36+
TEST_CHECK_CONTEXT_EQUAL(event, "both", "event");
37+
TEST_CHECK_CONTEXT_EQUAL(event, "event", "event");
38+
TEST_CHECK_CONTEXT_EQUAL(event, "scope", "scope");
39+
40+
sentry_value_decref(event);
41+
}
42+
43+
#undef TEST_CHECK_CONTEXT_EQUAL
44+
45+
sentry_close();
46+
}
47+
48+
SENTRY_TEST(scope_extra)
49+
{
50+
SENTRY_TEST_OPTIONS_NEW(options);
51+
sentry_init(options);
52+
53+
#define TEST_CHECK_EXTRA_EQUAL(event, key, value) \
54+
do { \
55+
sentry_value_t extra = sentry_value_get_by_key(event, "extra"); \
56+
TEST_CHECK_STRING_EQUAL( \
57+
sentry_value_as_string(sentry_value_get_by_key(extra, key)), \
58+
value); \
59+
} while (0)
60+
61+
// scope: {"both":"scope","scope":"scope"}
62+
sentry_set_extra("both", sentry_value_new_string("scope"));
63+
sentry_set_extra("scope", sentry_value_new_string("scope"));
64+
65+
SENTRY_WITH_SCOPE (scope) {
66+
// event: {"both":"event","event":"event"}
67+
sentry_value_t event = sentry_value_new_object();
68+
{
69+
sentry_value_t extra = sentry_value_new_object();
70+
sentry_value_set_by_key(
71+
extra, "both", sentry_value_new_string("event"));
72+
sentry_value_set_by_key(
73+
extra, "event", sentry_value_new_string("event"));
74+
sentry_value_set_by_key(event, "extra", extra);
75+
}
76+
77+
// event <- scope: {"both":"event","event":"event","scope":"scope"}
78+
sentry__scope_apply_to_event(scope, options, event, SENTRY_SCOPE_NONE);
79+
TEST_CHECK_EXTRA_EQUAL(event, "both", "event");
80+
TEST_CHECK_EXTRA_EQUAL(event, "event", "event");
81+
TEST_CHECK_EXTRA_EQUAL(event, "scope", "scope");
82+
83+
sentry_value_decref(event);
84+
}
85+
86+
#undef TEST_CHECK_EXTRA_EQUAL
87+
88+
sentry_close();
89+
}
90+
91+
SENTRY_TEST(scope_tags)
92+
{
93+
SENTRY_TEST_OPTIONS_NEW(options);
94+
sentry_init(options);
95+
96+
#define TEST_CHECK_TAG_EQUAL(event, key, value) \
97+
do { \
98+
sentry_value_t tags = sentry_value_get_by_key(event, "tags"); \
99+
TEST_CHECK_STRING_EQUAL( \
100+
sentry_value_as_string(sentry_value_get_by_key(tags, key)), \
101+
value); \
102+
} while (0)
103+
104+
// scope: {"both":"scope","scope":"scope"}
105+
sentry_set_tag("both", "scope");
106+
sentry_set_tag("scope", "scope");
107+
108+
SENTRY_WITH_SCOPE (scope) {
109+
// event: {"both":"event","event":"event"}
110+
sentry_value_t event = sentry_value_new_object();
111+
{
112+
sentry_value_t tags = sentry_value_new_object();
113+
sentry_value_set_by_key(
114+
tags, "both", sentry_value_new_string("event"));
115+
sentry_value_set_by_key(
116+
tags, "event", sentry_value_new_string("event"));
117+
sentry_value_set_by_key(event, "tags", tags);
118+
}
119+
120+
// event <- scope: {"both":"event","event":"event","scope":"scope"}
121+
sentry__scope_apply_to_event(scope, options, event, SENTRY_SCOPE_NONE);
122+
TEST_CHECK_TAG_EQUAL(event, "both", "event");
123+
TEST_CHECK_TAG_EQUAL(event, "event", "event");
124+
TEST_CHECK_TAG_EQUAL(event, "scope", "scope");
125+
126+
sentry_value_decref(event);
127+
}
128+
129+
#undef TEST_CHECK_TAG_EQUAL
130+
131+
sentry_close();
132+
}

tests/unit/test_value.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ SENTRY_TEST(value_object_merge)
308308
sentry_value_t b = sentry_value_get_by_key(dst, "b");
309309
sentry_value_t c = sentry_value_get_by_key(dst, "c");
310310
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(a), 1);
311-
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(b), 20);
311+
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(b), 2);
312312
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(c), 30);
313313

314314
sentry_value_decref(dst);
@@ -340,7 +340,7 @@ SENTRY_TEST(value_object_merge_nested)
340340
sentry_value_t bc = sentry_value_get_by_key(nested, "bc");
341341
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(a), 1);
342342
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(ba), 1);
343-
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(bb), 20);
343+
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(bb), 2);
344344
TEST_CHECK_INT_EQUAL(sentry_value_as_int32(bc), 30);
345345

346346
sentry_value_decref(dst);

tests/unit/tests.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ XX(recursive_paths)
8888
XX(sampling_before_send)
8989
XX(sampling_decision)
9090
XX(sampling_transaction)
91+
XX(scope_contexts)
92+
XX(scope_extra)
93+
XX(scope_tags)
9194
XX(scoped_txn)
9295
XX(sentry__value_span_new_requires_unfinished_parent)
9396
XX(serialize_envelope)

0 commit comments

Comments
 (0)