sentry-dotnet icon indicating copy to clipboard operation
sentry-dotnet copied to clipboard

Event timestamp serialization from JSON

Open arend-melissant-tnt opened this issue 1 year ago • 7 comments

Package

Sentry

.NET Flavor

.NET

.NET Version

8.0

OS

Any (not platform specific)

SDK Version

4.0.0

Self-Hosted Sentry Version

No response

Steps to Reproduce

read envelope from incoming message (using sentry-cli send-event) deserialize envelope using var envelope = await Envelope.DeserializeAsync(stream);

this will throw an exception: The requested operation requires an element of type 'String', but the target element has type 'Number'.

this is an the "timestamp" element of the event payload

Expected Result

timestamp should deserialize with either a string or number (per SDK)

Actual Result

Exception thrown

arend-melissant-tnt avatar Feb 02 '24 09:02 arend-melissant-tnt

read envelope from incoming message (using sentry-cli send-event)
deserialize envelope using var envelope = await Envelope.DeserializeAsync(stream);

There might be something to fix here but to to clarify: An envelope and an event are different things. Envelopes contain items, and one of those could be an event.

What are you trying to accomplish? we might be able to help you differently

bruno-garcia avatar Feb 02 '24 22:02 bruno-garcia

Hi,

I'm just trying to deserialize an complete received envelope, which fails if it contains an event with a timestamp formatted as a number. When te timestamp is formatted as a string everything works as expected. I do see in the code (or so it seems) that timestamps as numbers are not supported, but that should be supported as even the sentry-cli sends such events.

arend-melissant-tnt avatar Feb 03 '24 06:02 arend-melissant-tnt

Happy to help but I'm not quite following how to reproduce the issue you're running into: You're sending an event via sentry-cli but how and why does that generated envelope end up in the .NET SDK? The stream is just the deserialized envelope you're picking up from somewhere?

bitsandfoxes avatar Feb 05 '24 11:02 bitsandfoxes

I'm forwarding messages to Sentry, that's how I get the messages. I'll create a small test for you to see what's happening

arend-melissant-tnt avatar Feb 05 '24 14:02 arend-melissant-tnt

DeserialisationTests.txt

this is a simple unit test to recreate the issue

see https://develop.sentry.dev/sdk/event-payloads/ where it is explained that the timestamp can be either a string or a number

arend-melissant-tnt avatar Feb 05 '24 16:02 arend-melissant-tnt

I see. Yeah, we rely on GetDateTimeOffset() in System.Text.Json.JsonElement and that strictly expects a string to parse. I guess we could check the valuetype when parsing from json to event?

bitsandfoxes avatar Feb 06 '24 13:02 bitsandfoxes

I think we're looking for something like

json.TryGetProperty("timestamp", out var timestampElement);
DateTimeOffset? timestamp = null;
if (timestampElement.ValueKind == JsonValueKind.String)
{
    timestamp = timestampElement.GetDateTimeOffset();
}
else if (timestampElement.ValueKind == JsonValueKind.Number)
{
    timestamp = DateTimeOffset.FromUnixTimeSeconds((long)timestampElement.GetDouble());
}

instead of https://github.com/getsentry/sentry-dotnet/blob/ee3ea36e0de38a6bbd5a1ccec5f7c4922f237dce/src/Sentry/SentryEvent.cs#L293 @arend-melissant-tnt, would you be willing to open a PR for this?

bitsandfoxes avatar Feb 29 '24 12:02 bitsandfoxes