Skip to content

fix(api): APISpan no longer exposes what it recorded - #140

Open
michaelbushe wants to merge 1 commit into
mainfrom
fix/66-readable-span
Open

michaelbushe wants to merge 1 commit into
mainfrom
fix/66-readable-span

Conversation

@michaelbushe

Copy link
Copy Markdown
Member

Fixes #66.

What

APISpan exposed attributes, spanEvents, spanLinks, status and statusDescription. trace/api.md, Span:

Spans are not meant to be used to propagate information within a process. To prevent misuse, implementations SHOULD NOT provide access to a Span's attributes besides its SpanContext.

The attributes getter carried @visibleForTesting, which is an analyzer hint only. The getter was still public API, and a dynamic call reached it with no warning at all.

How

The five accessors move to a ReadableSpan, reached through getReadableSpan(span). Both are declared in a new part of span.dart, because the fields they read are library-private, and both are hidden from the package barrel:

export 'src/api/trace/span.dart'
    hide APISpanCreate, ReadableSpan, getReadableSpan;

Both carry @internal. An SDK reaches them by importing src/api/trace/span.dart directly and suppressing the lint at that one import, the same shape as the // ignore: invalid_use_of_visible_for_testing_member the SDK carries today, moved to one place.

The attributes setter is unchanged.

Verification

  • A barrel-only import can no longer reach them. I compiled a probe doing span.attributes against the public library and got undefined_getter.
  • dart analyze clean, dart test 1231 passing.
  • 127 call sites across 8 test files rewritten to getReadableSpan(...).
  • The web example no longer prints the span's status back out. Sample code should not teach the misuse the spec warns about.

SDK impact

This breaks dartastic_opentelemetry's Span, which re-exposes all five by delegation, as @harshitt13 found on #66. Tracked separately on the SDK side. The SDK is pinned below rc.4, so nothing breaks for users until that lands and the pin is widened.

Severity

SDK users are unaffected in practice: the SDK's own Span gates every mutator on its independent recording state, so this reaches API-direct users and custom SDKs.

🤖 Generated with Claude Code

trace/api.md, Span: implementations SHOULD NOT provide access to a Span's
attributes besides its SpanContext, because spans are not meant to
propagate information within a process.

APISpan exposed attributes, spanEvents, spanLinks, status and
statusDescription. The attributes getter carried @VisibleForTesting,
which is an analyzer hint: the getter was still public API and a dynamic
call reached it with no warning at all.

The five accessors move to a ReadableSpan, reached through
getReadableSpan(span). Both are declared in a part of span.dart, because
the fields they read are library-private, and both are hidden from the
package barrel, so code importing the public library cannot reach them.
Both carry @internal. An SDK imports src/api/trace/span.dart directly and
suppresses the resulting lint at that one import.

The attributes setter is unchanged. Reading back a span's status is
removed from the web example, since sample code should not teach the
misuse the spec warns about.

Fixes #66

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

[BUG] Trace API: APISpan exposes attributes, events, links, and status

1 participant