Skip to content

Commit 8b2a727

Browse files
authored
bugfix: refactor event metadata and fix request field (#10)
1 parent 93e57ad commit 8b2a727

File tree

6 files changed

+90
-46
lines changed

6 files changed

+90
-46
lines changed

sentry_sdk/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .utils import Dsn
55
from .transport import Transport
66
from .consts import DEFAULT_OPTIONS, SDK_INFO
7-
from .stripping import strip_event
7+
from .stripping import strip_event, flatten_metadata
88

99

1010
NO_DSN = object()
@@ -58,15 +58,15 @@ def _prepare_event(self, event, scope):
5858
if event.get('platform') is None:
5959
event['platform'] = 'python'
6060

61-
if event.get('') is None:
62-
event, event_meta = strip_event(event)
63-
event[""] = event_meta
61+
event = strip_event(event)
62+
event = flatten_metadata(event)
63+
return event
6464

6565
def capture_event(self, event, scope=None):
6666
"""Captures an event."""
6767
if self._transport is None:
6868
return
69-
self._prepare_event(event, scope)
69+
event = self._prepare_event(event, scope)
7070
self._transport.capture_event(event)
7171

7272
def drain_events(self, timeout=None):

sentry_sdk/hub.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def capture_exception(self, error=None):
138138
}
139139
return self.capture_event(event)
140140
except Exception:
141-
capture_internal_exception()
141+
self.capture_internal_exception()
142142

143143
def capture_internal_exception(self, error=None):
144144
"""Capture an exception that is likely caused by a bug in the SDK

sentry_sdk/integrations/flask.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ def _before_request(*args, **kwargs):
6363
try:
6464
scope.user = _get_user_info()
6565
except Exception:
66-
raise
6766
get_current_hub().capture_internal_exception()
6867
except Exception:
6968
get_current_hub().capture_internal_exception()

sentry_sdk/scope.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ def apply_to_event(self, event):
6565
if tags:
6666
event.setdefault('tags', {}).update(tags)
6767

68+
tags = self._data.get('request')
69+
if tags:
70+
event.setdefault('request', {}).update(tags)
71+
6872
contexts = self._data.get('contexts')
6973
if contexts:
7074
event.setdefault('contexts', {}).update(contexts)

sentry_sdk/stripping.py

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,87 @@
22

33
from ._compat import text_type
44

5+
6+
class AnnotatedValue(object):
7+
def __init__(self, value, metadata):
8+
self.value = value
9+
self.metadata = metadata
10+
11+
12+
def flatten_metadata(obj):
13+
def inner(obj):
14+
if isinstance(obj, Mapping):
15+
assert "" not in obj, "Merging metadata not supported"
16+
rv = {}
17+
meta = {}
18+
for k, v in obj.items():
19+
rv[k], meta[k] = inner(v)
20+
if meta[k] is None:
21+
del meta[k]
22+
return rv, (meta or None)
23+
if isinstance(obj, Sequence) and not isinstance(obj, (text_type, bytes)):
24+
rv = []
25+
meta = {}
26+
for i, v in enumerate(obj):
27+
new_v, meta[i] = inner(v)
28+
rv.append(new_v)
29+
if meta[i] is None:
30+
del meta[i]
31+
return rv, (meta or None)
32+
if isinstance(obj, AnnotatedValue):
33+
return obj.value, {"": obj.metadata}
34+
return obj, None
35+
36+
obj, meta = inner(obj)
37+
if meta is not None:
38+
obj[''] = meta
39+
return obj
40+
41+
542
def strip_event(event):
6-
assert "" not in event, "Merging metadata not supported"
7-
old_frames = event.get('stacktrace', {}).get('frames', [])
8-
new_frames = []
9-
frames_meta = {}
10-
meta = {"stacktrace": {"frames": frames_meta}}
43+
old_frames = event.get('stacktrace', {}).get('frames', None)
44+
if old_frames:
45+
event['stacktrace']['frames'] = [strip_frame(frame)
46+
for frame in old_frames]
1147

12-
for i, frame in old_frames:
13-
frame_meta, new_frame = strip_frame(frame)
14-
new_frames.append(new_frame)
15-
if frame_meta is not None:
16-
frames_meta[str(i)] = frame_meta
48+
old_request_data = event.get('request', {}).get('data', None)
49+
if old_request_data:
50+
event['request']['data'] = strip_databag(old_request_data)
1751

18-
return event, meta
52+
return event
1953

2054
def strip_frame(frame):
2155
frame['vars'], meta = strip_databag(frame.get('vars'))
2256
return frame, ({"vars": meta} if meta is not None else None)
2357

2458
def strip_databag(obj, remaining_depth=20):
59+
assert not isinstance(obj, bytes), 'bytes should have been normalized before'
2560
if remaining_depth <= 0:
26-
return None, {"": {"rem": [["!dep", "x"]]}}
61+
return AnnotatedValue(None, {"": {"rem": [["!dep", "x"]]}})
2762
if isinstance(obj, text_type):
2863
return strip_string(obj)
2964
if isinstance(obj, Mapping):
30-
rv = {}
31-
meta = {}
32-
for k, v in obj.items():
33-
rv[k], v_meta = strip_databag(v, remaining_depth - 1)
34-
if v_meta is not None:
35-
meta[k] = v_meta
36-
return rv, meta
65+
return {k: strip_databag(v, remaining_depth - 1)
66+
for k, v in obj.items()}
3767
if isinstance(obj, Sequence):
38-
rv = []
39-
meta = {}
40-
for i, v in enumerate(obj):
41-
new_v, v_meta = strip_databag(obj, remaining_depth - 1)
42-
rv.append(new_v)
43-
if v_meta is not None:
44-
meta[str(i)] = v_meta
45-
return rv, meta
68+
return [strip_databag(v, remaining_depth - 1)
69+
for v in obj]
70+
return obj
4671

47-
return obj, None
4872

49-
50-
def strip_string(value, length=512):
73+
def strip_string(value, assume_length=None, max_length=512):
74+
# TODO: read max_length from config
5175
if not value:
52-
return value, None
53-
if len(value) > length:
54-
meta = {
55-
"": {
56-
"len": len(value),
57-
"rem": [["!len", "x", length, len(value)]]
76+
return value
77+
if assume_length is None:
78+
assume_length = len(value)
79+
80+
if assume_length > max_length:
81+
return AnnotatedValue(
82+
value=value[:max_length - 3] + u'...',
83+
metadata={
84+
"len": assume_length,
85+
"rem": [["!len", "x", max_length - 3, max_length]]
5886
}
59-
}
60-
return value[:length - 3] + '...', meta
61-
return value[:length], None
87+
)
88+
return value[:max_length]

tests/test_stripping.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from sentry_sdk.stripping import AnnotatedValue, flatten_metadata, strip_databag
2+
3+
def test_flatten_metadata():
4+
assert flatten_metadata({'foo': u'bar'}) == {'foo': u'bar'}
5+
assert flatten_metadata({'foo': ['bar']}) == {'foo': [u'bar']}
6+
assert flatten_metadata({'foo': [AnnotatedValue('bar', u'meta')]}) == {
7+
'foo': [u'bar'],
8+
'': {'foo': {0: {'': u'meta'}}}
9+
}
10+
11+
12+
def test_strip_databag():
13+
d = strip_databag({'foo': u'a' * 2000})
14+
assert len(d['foo'].value) == 512

0 commit comments

Comments
 (0)