Browse Source

Fixes #173 coerce span tags to string values

David Burke 2 years ago
parent
commit
bc8a2573f4

+ 2 - 1
events/test_data/transactions/django_simple.json

@@ -37,7 +37,8 @@
         "timestamp": "2020-12-29T17:51:08.467908Z",
         "tags": {
           "django.function_name": "django.utils.deprecation.MiddlewareMixin.__call__",
-          "django.middleware_name": "django.middleware.security.SecurityMiddleware"
+          "django.middleware_name": "django.middleware.security.SecurityMiddleware",
+          "bad": true
         }
       },
       {

+ 5 - 1
events/views.py

@@ -178,7 +178,11 @@ class EnvelopeAPIView(BaseEventAPIView):
             serializer = self.get_serializer_class()(
                 data=data.pop(0), context={"request": self.request, "project": project}
             )
-            serializer.is_valid(raise_exception=True)
+            try:
+                serializer.is_valid(raise_exception=True)
+            except exceptions.ValidationError as err:
+                logger.warning("Invalid envelope payload", exc_info=True)
+                raise err
             try:
                 event = serializer.save()
             except IntegrityError as err:

+ 7 - 0
performance/serializers.py

@@ -53,6 +53,13 @@ class SpanSerializer(serializers.ModelSerializer):
             "parent_span_id": {"write_only": True},
         }
 
+    def to_internal_value(self, data):
+        # Coerce tags to strings
+        # Must be done here to avoid failing child CharField validation
+        if tags := data.get("tags"):
+            data["tags"] = {key: str(value) for key, value in tags.items()}
+        return super().to_internal_value(data)
+
 
 class TransactionEventSerializer(SentrySDKEventSerializer):
     type = serializers.CharField(required=False)

+ 1 - 1
users/models.py

@@ -86,7 +86,7 @@ class User(AbstractBaseUser, PermissionsMixin):
         default=True,
         help_text="Subscribe to project notifications by default. Overrides project settings",
     )
-    options = models.JSONField(default={})
+    options = models.JSONField(default=dict)
     USERNAME_FIELD = "email"
     EMAIL_FIELD = "email"
     objects = UserManager()