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

[ISSUE-5161] Fix panics if a nil context is provided to the .Start() method #5162

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

xxbtwxx
Copy link

@xxbtwxx xxbtwxx commented Apr 5, 2024

Fix for #5161

As agreed by this discussion, the implementation should not throw unhandled exceptions at run time.

Copy link

linux-foundation-easycla bot commented Apr 5, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@dmathieu
Copy link
Member

dmathieu commented Apr 5, 2024

Could you add tests?

trace/noop.go Outdated Show resolved Hide resolved
@MrAlias
Copy link
Contributor

MrAlias commented Apr 5, 2024

This seems like standard Go behavior. The context package explicitly states nil context should not be used:

20240405_072833

I do not think we should be adding boilerplate to all of our functions to prevent invalid user behavior in the eyes of Go.

@xxbtwxx
Copy link
Author

xxbtwxx commented Apr 5, 2024

This seems like standard Go behavior. The context package explicitly states nil context should not be used:

20240405_072833

I do not think we should be adding boilerplate to all of our functions to prevent invalid user behavior in the eyes of Go.

This was previously discussed and agreed upon here

Here's a link to the spec, that says:

API methods MUST NOT throw unhandled exceptions when used incorrectly by end users. The API and SDK SHOULD provide safe defaults for missing or invalid arguments. For instance, a name like empty may be used if the user passes in null as the span name argument during Span construction.

@dmathieu
Copy link
Member

dmathieu commented Apr 8, 2024

I may be doing lawyer talk, but I'm not sure the specification works for this case.

API methods MUST NOT throw unhandled exceptions when used incorrectly by end users.

I read this specification as saying that the SDK's API methods should not throw unhandled exceptions when the SDK's API methods are used incorrectly by end-users.
Not if an external API (in this case, context.Context) is used incorrectly.

This was previously discussed and agreed upon #3110 (comment)

This comment is not an agreement. It's a single approver's opinion (which is not to be dismissed either of course).
cc @dashpole

Copy link

codecov bot commented Apr 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.8%. Comparing base (014c6fc) to head (c7f4d78).
Report is 427 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #5162   +/-   ##
=====================================
  Coverage   83.8%   83.8%           
=====================================
  Files        254     254           
  Lines      16532   16538    +6     
=====================================
+ Hits       13864   13870    +6     
  Misses      2375    2375           
  Partials     293     293           
Files with missing lines Coverage Δ
internal/global/trace.go 85.1% <100.0%> (+0.6%) ⬆️
trace/noop.go 59.0% <100.0%> (+4.0%) ⬆️
trace/noop/noop.go 100.0% <100.0%> (ø)

@xxbtwxx
Copy link
Author

xxbtwxx commented Apr 8, 2024

I may be doing lawyer talk, but I'm not sure the specification works for this case.

API methods MUST NOT throw unhandled exceptions when used incorrectly by end users.

I read this specification as saying that the SDK's API methods should not throw unhandled exceptions when the SDK's API methods are used incorrectly by end-users. Not if an external API (in this case, context.Context) is used incorrectly.

I would agree with this if the second part of the spec was not included
The API and SDK SHOULD provide safe defaults for missing or invalid arguments.
With a nil context clearly being an invalid argument

@dashpole
Copy link
Contributor

dashpole commented Apr 8, 2024

My reading of the spec is that we are required not to panic on nil context for API methods. It is also an improper use of go's Context, but i'm not sure that changes anything.

This comment is not an agreement. It's a single approver's opinion

Thats correct. I'm happy to be overruled by other approvers here.

But I don't think this needs to be a lot of boilerplate, since we don't actually need to add a nil check everywhere. IMO we should just update ContextWithSpan to handle a nil parent context here:

func ContextWithSpan(parent context.Context, span Span) context.Context {
return context.WithValue(parent, currentSpanKey, span)
}

I've checked all of our metric and trace APIs that accept a context.Context, and all of our usage is either to call trace.SpanFromContext, or trace.ContextWithSpan (or a method that calls one of those two). We already check for nil in trace.SpanFromContext:

func SpanFromContext(ctx context.Context) Span {
if ctx == nil {
return noopSpanInstance
}

If we did decide to go that route, it would be good, IMO to add the TestNoPanic tests from this PR, and also to our metrics and logs APIs.

@pellared
Copy link
Member

pellared commented Apr 9, 2024

since we don't actually need to add a nil check everywhere

What about all API methods that accepts interfaces like Span, SpanStartOption, TracerOption, Int64CounterOption?

E.g. do we want to add nil-checks in the code below?

func NewInt64ObservableUpDownCounterConfig(opts ...Int64ObservableUpDownCounterOption) Int64ObservableUpDownCounterConfig {
var config Int64ObservableUpDownCounterConfig
for _, o := range opts {
config = o.applyInt64ObservableUpDownCounter(config)
}
return config
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants