Skip to content

Commit

Permalink
Fixed baggage propagation when an exception is thrown from middleware (
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescrosswell authored Jul 17, 2023
1 parent f6aca1c commit d6d531c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixes

- Fixes baggage propagation when an exception is thrown from middleware ([#2487](https://github.com/getsentry/sentry-dotnet/pull/2487))

### Dependencies

- Bump Java SDK from v6.25.1 to v6.25.2 ([#2484](https://github.com/getsentry/sentry-dotnet/pull/2484))
Expand Down
10 changes: 10 additions & 0 deletions src/Sentry/Extensibility/HubAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public ITransaction StartTransaction(
IReadOnlyDictionary<string, object?> customSamplingContext)
=> SentrySdk.StartTransaction(context, customSamplingContext);

/// <summary>
/// Forwards the call to <see cref="SentrySdk"/>.
/// </summary>
[DebuggerStepThrough]
internal ITransaction StartTransaction(
ITransactionContext context,
IReadOnlyDictionary<string, object?> customSamplingContext,
DynamicSamplingContext? dynamicSamplingContext)
=> SentrySdk.StartTransaction(context, customSamplingContext, dynamicSamplingContext);

/// <summary>
/// Forwards the call to <see cref="SentrySdk"/>.
/// </summary>
Expand Down
11 changes: 7 additions & 4 deletions src/Sentry/HubExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Sentry.Extensibility;
using Sentry.Infrastructure;
using Sentry.Internal;
using Sentry.Internal.Extensions;
Expand Down Expand Up @@ -227,10 +228,12 @@ internal static ITransaction StartTransaction(
this IHub hub,
ITransactionContext context,
IReadOnlyDictionary<string, object?> customSamplingContext,
DynamicSamplingContext? dynamicSamplingContext)
=> hub is Hub fullHub
? fullHub.StartTransaction(context, customSamplingContext, dynamicSamplingContext)
: hub.StartTransaction(context, customSamplingContext);
DynamicSamplingContext? dynamicSamplingContext) => hub switch
{
Hub fullHub => fullHub.StartTransaction(context, customSamplingContext, dynamicSamplingContext),
HubAdapter adapter => adapter.StartTransaction(context, customSamplingContext, dynamicSamplingContext),
_ => hub.StartTransaction(context, customSamplingContext)
};

internal static ITransaction? GetTransaction(this IHub hub)
{
Expand Down
9 changes: 7 additions & 2 deletions src/Sentry/Internal/Hub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ SentryId IHubEx.CaptureEventInternal(SentryEvent evt, Hint? hint, Scope? scope)
evt.Contexts.Trace.SpanId = linkedSpan.SpanId;
evt.Contexts.Trace.TraceId = linkedSpan.TraceId;
evt.Contexts.Trace.ParentSpanId = linkedSpan.ParentSpanId;
// Try to read the DSC from the transaction associated with the linked span
if (linkedSpan?.GetTransaction() is TransactionTracer transactionTracer)
{
evt.DynamicSamplingContext = transactionTracer.DynamicSamplingContext;
}
}

var hasTerminalException = evt.HasTerminalException();
Expand All @@ -360,9 +365,9 @@ SentryId IHubEx.CaptureEventInternal(SentryEvent evt, Hint? hint, Scope? scope)
actualScope.SessionUpdate = _sessionManager.ReportError();
}

// When a transaction is present, copy its DSC to the event.
// Try to get the DSC from the transaction, if we didn't get it already from the linked span
var transaction = actualScope.Transaction as TransactionTracer;
evt.DynamicSamplingContext = transaction?.DynamicSamplingContext;
evt.DynamicSamplingContext ??= transaction?.DynamicSamplingContext;

// Now capture the event with the Sentry client on the current scope.
var sentryClient = currentScope.Value;
Expand Down
40 changes: 40 additions & 0 deletions test/Sentry.Tests/HubTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,46 @@ public void CaptureException_ActiveSpanExistsOnScope_EventIsLinkedToSpan()
Arg.Any<Scope>());
}

[Fact]
public void CaptureException_TransactionFinished_Gets_DSC_From_LinkedSpan()
{
// Arrange
_fixture.Options.TracesSampleRate = 1.0;
var hub = _fixture.GetSut();
var exception = new Exception("error");

var traceHeader = new SentryTraceHeader(
SentryId.Parse("75302ac48a024bde9a3b3734a82e36c8"),
SpanId.Parse("2000000000000000"),
true);
var transactionContext = new TransactionContext("foo", "bar", traceHeader);

var dsc = BaggageHeader.Create(new List<KeyValuePair<string, string>>
{
{"sentry-sample_rate", "1.0"},
{"sentry-trace_id", "75302ac48a024bde9a3b3734a82e36c8"},
{"sentry-public_key", "d4d82fc1c2c4032a83f3a29aa3a3aff"},
{"sentry-replay_id","bfd31b89a59d41c99d96dc2baf840ecd"}
}).CreateDynamicSamplingContext();

var transaction = hub.StartTransaction(
transactionContext,
new Dictionary<string, object>(),
dsc
);
transaction.Finish(exception);

// Act
hub.CaptureException(exception);

// Assert
_fixture.Client.Received(1).CaptureEvent(
Arg.Is<SentryEvent>(evt =>
evt.DynamicSamplingContext == dsc),
Arg.Any<Hint>(),
Arg.Any<Scope>());
}

[Fact]
public void CaptureException_ActiveSpanExistsOnScopeButIsSampledOut_EventIsNotLinkedToSpan()
{
Expand Down

0 comments on commit d6d531c

Please sign in to comment.