Skip to content

Commit e234998

Browse files
dashedrhcarvalhomarkstory
authored
feat(envelope): Add some useful envelope methods (#793)
Co-authored-by: Rodolfo Carvalho <[email protected]> Co-authored-by: Mark Story <[email protected]>
1 parent 920e562 commit e234998

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

sentry_sdk/envelope.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sentry_sdk._compat import text_type
77
from sentry_sdk._types import MYPY
88
from sentry_sdk.sessions import Session
9+
from sentry_sdk.tracing import Transaction
910
from sentry_sdk.utils import json_dumps
1011

1112
if MYPY:
@@ -50,6 +51,12 @@ def add_event(
5051
# type: (...) -> None
5152
self.add_item(Item(payload=PayloadRef(json=event), type="event"))
5253

54+
def add_transaction(
55+
self, transaction # type: Transaction
56+
):
57+
# type: (...) -> None
58+
self.add_item(Item(payload=PayloadRef(json=transaction), type="transaction"))
59+
5360
def add_session(
5461
self, session # type: Union[Session, Any]
5562
):
@@ -72,6 +79,14 @@ def get_event(self):
7279
return event
7380
return None
7481

82+
def get_transaction_event(self):
83+
# type: (...) -> Optional[Event]
84+
for item in self.items:
85+
event = item.get_transaction_event()
86+
if event is not None:
87+
return event
88+
return None
89+
7590
def __iter__(self):
7691
# type: (...) -> Iterator[Item]
7792
return iter(self.items)
@@ -220,6 +235,11 @@ def __repr__(self):
220235
self.data_category,
221236
)
222237

238+
@property
239+
def type(self):
240+
# type: (...) -> Optional[str]
241+
return self.headers.get("type")
242+
223243
@property
224244
def data_category(self):
225245
# type: (...) -> EventDataCategory
@@ -244,7 +264,13 @@ def get_event(self):
244264
"""
245265
Returns an error event if there is one.
246266
"""
247-
if self.headers.get("type") == "event" and self.payload.json is not None:
267+
if self.type == "event" and self.payload.json is not None:
268+
return self.payload.json
269+
return None
270+
271+
def get_transaction_event(self):
272+
# type: (...) -> Optional[Event]
273+
if self.type == "transaction" and self.payload.json is not None:
248274
return self.payload.json
249275
return None
250276

@@ -277,7 +303,7 @@ def deserialize_from(
277303
headers = json.loads(line)
278304
length = headers["length"]
279305
payload = f.read(length)
280-
if headers.get("type") == "event":
306+
if headers.get("type") in ("event", "transaction"):
281307
rv = cls(headers=headers, payload=PayloadRef(json=json.loads(payload)))
282308
else:
283309
rv = cls(headers=headers, payload=payload)

tests/test_envelope.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from sentry_sdk.envelope import Envelope
2+
from sentry_sdk.sessions import Session
3+
4+
5+
def generate_transaction_item():
6+
return {
7+
"event_id": "d2132d31b39445f1938d7e21b6bf0ec4",
8+
"type": "transaction",
9+
"transaction": "/organizations/:orgId/performance/:eventSlug/",
10+
"start_timestamp": 1597976392.6542819,
11+
"timestamp": 1597976400.6189718,
12+
"contexts": {
13+
"trace": {
14+
"trace_id": "4C79F60C11214EB38604F4AE0781BFB2",
15+
"span_id": "FA90FDEAD5F74052",
16+
"type": "trace",
17+
}
18+
},
19+
"spans": [
20+
{
21+
"description": "<OrganizationContext>",
22+
"op": "react.mount",
23+
"parent_span_id": "8f5a2b8768cafb4e",
24+
"span_id": "bd429c44b67a3eb4",
25+
"start_timestamp": 1597976393.4619668,
26+
"timestamp": 1597976393.4718769,
27+
"trace_id": "ff62a8b040f340bda5d830223def1d81",
28+
}
29+
],
30+
}
31+
32+
33+
def test_basic_event():
34+
envelope = Envelope()
35+
36+
expected = {"message": "Hello, World!"}
37+
envelope.add_event(expected)
38+
39+
assert envelope.get_event() == {"message": "Hello, World!"}
40+
41+
42+
def test_transaction_event():
43+
envelope = Envelope()
44+
45+
transaction_item = generate_transaction_item()
46+
transaction_item.update({"event_id": "a" * 32})
47+
envelope.add_transaction(transaction_item)
48+
49+
# typically it should not be possible to be able to add a second transaction;
50+
# but we do it anyways
51+
another_transaction_item = generate_transaction_item()
52+
envelope.add_transaction(another_transaction_item)
53+
54+
# should only fetch the first inserted transaction event
55+
assert envelope.get_transaction_event() == transaction_item
56+
57+
58+
def test_session():
59+
envelope = Envelope()
60+
61+
expected = Session()
62+
envelope.add_session(expected)
63+
64+
for item in envelope:
65+
if item.type == "session":
66+
assert item.payload.json == expected.to_json()

0 commit comments

Comments
 (0)