Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tracer to guard for a nil ctx #3110

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The exponential histogram mapping functions have been updated with
exact upper-inclusive boundary support following the [corresponding
specification change](https://github.com/open-telemetry/opentelemetry-specification/pull/2633). (#2982)
- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110)

## [1.9.0/0.0.3] - 2022-08-01

Expand Down
10 changes: 10 additions & 0 deletions sdk/trace/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,16 @@ func TestStartSpanWithParent(t *testing.T) {
}
}

// Test we get a successful span as a new root if a nil context is sent in, as opposed to a panic.
// See https://github.com/open-telemetry/opentelemetry-go/issues/3109
func TestStartSpanWithNilContext(t *testing.T) {
tp := NewTracerProvider()
tr := tp.Tracer("NoPanic")

// nolint:staticcheck // no nil context, but that's the point of the test.
assert.NotPanics(t, func() { tr.Start(nil, "should-not-panic") })
}

func TestStartSpanNewRootNotSampled(t *testing.T) {
alwaysSampleTp := NewTracerProvider()
sampledTr := alwaysSampleTp.Tracer("AlwaysSampled")
Expand Down
5 changes: 5 additions & 0 deletions sdk/trace/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ var _ trace.Tracer = &tracer{}
func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
config := trace.NewSpanStartConfig(options...)

if ctx == nil {
// Prevent trace.ContextWithSpan from panicking.
ctx = context.Background()
}

// For local spans created by this SDK, track child span count.
if p := trace.SpanFromContext(ctx); p != nil {
if sdkSpan, ok := p.(*recordingSpan); ok {
Expand Down