diff --git a/CHANGELOG.md b/CHANGELOG.md index ca66fa510..4442cb5bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +### Bug Fixes + +- fix(dynamic-sampling): Do not crash in Span.Finish() when Client is empty [#520](https://github.com/getsentry/sentry-go/pull/520) + - Fixes [#518](https://github.com/getsentry/sentry-go/issues/518) + ## 0.16.0 The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.16.0. diff --git a/dynamic_sampling_context.go b/dynamic_sampling_context.go index 3e54839ba..06feb2195 100644 --- a/dynamic_sampling_context.go +++ b/dynamic_sampling_context.go @@ -43,6 +43,14 @@ func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext { hub := hubFromContext(span.Context()) scope := hub.Scope() client := hub.Client() + + if client == nil || scope == nil { + return DynamicSamplingContext{ + Entries: map[string]string{}, + Frozen: false, + } + } + options := client.Options() if traceID := span.TraceID.String(); traceID != "" { diff --git a/dynamic_sampling_context_test.go b/dynamic_sampling_context_test.go index 6cca56591..5299bc1ea 100644 --- a/dynamic_sampling_context_test.go +++ b/dynamic_sampling_context_test.go @@ -1,6 +1,7 @@ package sentry import ( + "context" "strings" "testing" ) @@ -108,6 +109,18 @@ func TestDynamicSamplingContextFromTransaction(t *testing.T) { }, }, }, + // Empty context without a valid Client + { + input: func() *Span { + ctx := context.Background() + tx := StartTransaction(ctx, "op") + return tx + }(), + want: DynamicSamplingContext{ + Frozen: false, + Entries: map[string]string{}, + }, + }, } for _, tc := range tests { diff --git a/tracing_test.go b/tracing_test.go index 8902f75d3..3cc13dff7 100644 --- a/tracing_test.go +++ b/tracing_test.go @@ -567,3 +567,12 @@ func TestSample(t *testing.T) { t.Fatalf("got %s, want %s", got, SampledTrue) } } + +func TestDoesNotCrashWithEmptyContext(t *testing.T) { + // This test makes sure that we can still start and finish transactions + // with empty context (for example, when Sentry SDK is not initialized) + ctx := context.Background() + tx := StartTransaction(ctx, "op") + tx.Sampled = SampledTrue + tx.Finish() +}