Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixes

- Unsampled spans no longer propagate empty trace headers ([#4302](https://github.com/getsentry/sentry-dotnet/pull/4302))

## 5.11.1

### Fixes
Expand Down
9 changes: 8 additions & 1 deletion src/Sentry.AspNetCore/Extensions/HttpContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ internal static class HttpContextExtensions

try
{
return SentryTraceHeader.Parse(value!);
var traceHeader = SentryTraceHeader.Parse(value!);
if (traceHeader?.TraceId != SentryId.Empty)
{
return traceHeader;
}

options?.LogWarning("Sentry trace header '{0}' has an empty trace ID.", value);
return null;
}
catch (Exception ex)
{
Expand Down
1 change: 1 addition & 0 deletions src/Sentry/Internal/UnsampledSpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ internal sealed class UnsampledSpan(UnsampledTransaction transaction, SpanId? sp
public override SpanId SpanId { get; } = spanId ?? SpanId.Empty;
internal UnsampledTransaction Transaction => transaction;
public override ISpan StartChild(string operation) => transaction.StartChild(operation);
public override SentryTraceHeader GetTraceHeader() => transaction.GetTraceHeader();
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,20 @@ public void TryGetRouteTemplate_WithSentryRouteName_RouteName()
// Assert
Assert.Equal(expectedName, filteredRoute);
}

[Fact]
public void TryGetSentryTraceHeader_WithEmptyTraceId_ReturnsNull()
{
// Arrange
var httpContext = Fixture.GetSut();
var options = new SentryOptions();
httpContext.Request.Headers.Append(SentryTraceHeader.HttpHeaderName, "00000000000000000000000000000000-1000000000000000-1");

// Act
var header = httpContext.TryGetSentryTraceHeader(options);

// Assert
Assert.Null(header);
}
}
#endif
24 changes: 24 additions & 0 deletions test/Sentry.Tests/Internals/UnsampledSpanTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Sentry.Tests.Internals;

public class UnsampledSpanTests
{
[Fact]
public void GetTraceHeader_CreatesHeaderFromUnsampledTransaction()
{
// Arrange
var hub = Substitute.For<IHub>();
ITransactionContext context = new TransactionContext("TestTransaction", "TestOperation",
new SentryTraceHeader(SentryId.Create(), SpanId.Create(), false)
);
var transaction = new UnsampledTransaction(hub, context);
var unsampledSpan = transaction.StartChild("Foo");

// Act
var traceHeader = unsampledSpan.GetTraceHeader();

// Assert
traceHeader.TraceId.Should().Be(context.TraceId);
traceHeader.SpanId.Should().Be(context.SpanId);
traceHeader.IsSampled.Should().Be(context.IsSampled);
}
}
Loading