Просмотр исходного кода

Insert "error" type into breadcrumb mock data

Ben Vinegar 9 лет назад
Родитель
Сommit
a7a7e67cf9

+ 64 - 55
bin/load-mocks

@@ -116,57 +116,12 @@ def milliseconds_ago(now, milliseconds):
     return (ago - epoch).total_seconds()
 
 
-def main(num_events=1):
-    user = User.objects.filter(is_superuser=True)[0]
-
-    dummy_user, _ = User.objects.get_or_create(
-        username='dummy@example.com',
-        defaults={
-            'email': 'dummy@example.com',
-        }
-    )
-    dummy_user.set_password('dummy')
-    dummy_user.save()
-
-    mocks = (
-        ('Massive Dynamic', ('Ludic Science',)),
-        ('Captain Planet', ('Earth', 'Fire', 'Wind', 'Water', 'Heart')),
-    )
-
-    Broadcast.objects.create(
-        title="Learn about Source Maps",
-        message="Source maps are JSON files that contain information on how to map your transpiled source code back to their original source.",
-        link="https://docs.getsentry.com/hosted/clients/javascript/sourcemaps/#uploading-source-maps-to-sentry",
-    )
-
-    if settings.SENTRY_SINGLE_ORGANIZATION:
-        org = Organization.get_default()
-    else:
-        print('Mocking org {}'.format('Default'))
-        org, _ = Organization.objects.get_or_create(
-            name='Default',
-        )
-
-    OrganizationMember.objects.get_or_create(
-        user=user,
-        organization=org,
-        role=roles.get_top_dog().id,
-    )
-
-    dummy_member, _ = OrganizationMember.objects.get_or_create(
-        user=dummy_user,
-        organization=org,
-        defaults={
-            'role': roles.get_default().id,
-        }
-    )
-
+def get_sample_breadcrumbs(prior_event_id=None):
     now = datetime.now()
     sample_breadcrumbs = {
         "values": [
             {
                 "type": "navigation",
-                "dt": 8200,
                 "timestamp": milliseconds_ago(now, 5200),
                 "data": {
                     "to": "http://example.com/dashboard/",
@@ -175,7 +130,6 @@ def main(num_events=1):
             },
             {
                 "type": "message",
-                "dt": 5000,
                 "timestamp": milliseconds_ago(now, 4000),
                 "data": {
                     "message": "This is a message breadcrumb",
@@ -184,7 +138,6 @@ def main(num_events=1):
             },
             {
                 "type": "message",
-                "dt": 4000,
                 "timestamp": milliseconds_ago(now, 3300),
                 "data": {
                     "message": "This is a warning message",
@@ -193,7 +146,6 @@ def main(num_events=1):
             },
             {
                 "type": "message",
-                "dt": 3500,
                 "timestamp": milliseconds_ago(now, 2700),
                 "data": {
                     "message": "This is an error message",
@@ -202,11 +154,10 @@ def main(num_events=1):
             },
             {
                 "type": "http_request",
-                "dt": 3000,
                 "timestamp": milliseconds_ago(now, 1300),
                 "data": {
                     "url": "http://example.com/foo",
-                    "statusCode": 200,
+                    "status_code": 200,
                     "method": "POST",
                     "headers": {
                         "Referer": "http://example.com",
@@ -216,7 +167,6 @@ def main(num_events=1):
             },
             {
                 "type": "ui_event",
-                "dt": 1500,
                 "timestamp": milliseconds_ago(now, 1000),
                 "data": {
                     "type": "click",
@@ -226,6 +176,63 @@ def main(num_events=1):
         ]
     }
 
+    if prior_event_id:
+        sample_breadcrumbs["values"].insert(2, {
+            "type": "error",
+            "timestamp": milliseconds_ago(now, 3000),
+            "data": {
+                "message": "TypeError: something broke earlier",
+                "event_id": prior_event_id
+            }
+        })
+
+    return sample_breadcrumbs
+
+def main(num_events=1):
+    user = User.objects.filter(is_superuser=True)[0]
+
+    dummy_user, _ = User.objects.get_or_create(
+        username='dummy@example.com',
+        defaults={
+            'email': 'dummy@example.com',
+        }
+    )
+    dummy_user.set_password('dummy')
+    dummy_user.save()
+
+    mocks = (
+        ('Massive Dynamic', ('Ludic Science',)),
+        ('Captain Planet', ('Earth', 'Fire', 'Wind', 'Water', 'Heart')),
+    )
+
+    Broadcast.objects.create(
+        title="Learn about Source Maps",
+        message="Source maps are JSON files that contain information on how to map your transpiled source code back to their original source.",
+        link="https://docs.getsentry.com/hosted/clients/javascript/sourcemaps/#uploading-source-maps-to-sentry",
+    )
+
+    if settings.SENTRY_SINGLE_ORGANIZATION:
+        org = Organization.get_default()
+    else:
+        print('Mocking org {}'.format('Default'))
+        org, _ = Organization.objects.get_or_create(
+            name='Default',
+        )
+
+    OrganizationMember.objects.get_or_create(
+        user=user,
+        organization=org,
+        role=roles.get_top_dog().id,
+    )
+
+    dummy_member, _ = OrganizationMember.objects.get_or_create(
+        user=dummy_user,
+        organization=org,
+        defaults={
+            'role': roles.get_default().id,
+        }
+    )
+
     for team_name, project_names in mocks:
         print('> Mocking team {}'.format(team_name))
         team, _ = Team.objects.get_or_create(
@@ -272,16 +279,18 @@ def main(num_events=1):
             )
 
             # Add a bunch of additional dummy events to support pagination
+            last_event = None
             for _ in range(45):
                 platform = PLATFORMS.next()
-                create_sample_event(
+
+                last_event = create_sample_event(
                     project=project,
                     platform=platform,
                     release=release.version,
                     level=LEVELS.next(),
                     message='This is a mostly useless example %s exception' % platform,
                     checksum=md5(platform + str(_)).hexdigest(),
-                    breadcrumbs=sample_breadcrumbs,
+                    breadcrumbs=get_sample_breadcrumbs(prior_event_id=last_event.id if last_event else None),
                 )
 
             for _ in range(num_events):
@@ -295,7 +304,7 @@ def main(num_events=1):
                     project=project,
                     platform='javascript',
                     release=release.version,
-                    breadcrumbs=sample_breadcrumbs,
+                    breadcrumbs=get_sample_breadcrumbs(prior_event_id=event1.event_id),
                 )
 
                 event3 = create_sample_event(project, 'java')

+ 11 - 1
src/sentry/interfaces/breadcrumbs.py

@@ -89,7 +89,7 @@ def validate_rpc(payload):
 @typevalidator('http_request')
 def validate_http_request(payload):
     rv = {}
-    for key in 'statusCode', 'reason', 'method', 'url', 'headers', \
+    for key in 'status_code', 'reason', 'method', 'url', 'headers', \
                'response', 'classifier':
         value = payload.get(key)
         if value is not None:
@@ -136,6 +136,16 @@ def validate_navigation(payload):
     return rv
 
 
+@typevalidator('error')
+def validate_error(payload):
+    rv = {}
+    for key in 'type', 'message', 'event_id':
+        value = payload.get(key)
+        if value is not None:
+            rv[key] = trim(value, 1024)
+    return rv
+
+
 class Breadcrumbs(Interface):
     """
     This interface stores informationt that leads up to an error in the

+ 11 - 3
src/sentry/static/sentry/app/components/events/interfaces/breadcrumbComponents/error.jsx

@@ -3,11 +3,19 @@ import React from 'react';
 import KeyValueList from '../keyValueList';
 
 function Error(props) {
-  let {type, value} = props.data;
+  let {type, value, message, eventId} = props.data;
 
   let list = [];
-  list.push(['type', type]);
-  list.push(['message', value]);
+  if (type && value) {
+    list.push(['type', type]);
+    list.push(['message', value]);
+  }
+  if (message) {
+    list.push(['message', message]);
+  }
+  if (eventId) {
+    list.push(['event_id', eventId]);
+  }
 
   return (
     <div>