Skip to content

semconv,sdk/log: unwrap single-error errors.Join wrappers in error type derivation - #9466

Merged
pellared merged 1 commit into
open-telemetry:mainfrom
dashpole:unwrap-single-errors-join
Nov 9, 2026
Merged

pellared merged 1 commit into
open-telemetry:mainfrom
dashpole:unwrap-single-errors-join

Conversation

@dashpole

@dashpole dashpole commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Part of #9446

Summary

In Go, errors.Join is commonly used to accumulate optional errors across operations—for example, uploadErr = errors.Join(uploadErr, err) where uploadErr starts as nil. When only one non-nil error is passed (e.g., errors.Join(nil, err)), errors.Join still wraps that single error in an unexported *errors.joinError implementing Unwrap() []error (not Unwrap() error).

When no error in the chain implements ErrorType() string, semconv.ErrorType and sdk/log fall back to reflection after unwrapping *fmt.wrapError (#8133). Because errors.Unwrap returns nil for Unwrap() []error, single-error errors.Join wrappers were not unwrapped and caused instrumentation and SDK self-observability metrics to report the opaque error.type="*errors.joinError" instead of the underlying error's concrete type.

Approach

  • Extend the reflection-fallback unwrapping helper in internal/tools/semconvkit/templates/error_type.go.tmpl, semconv/v1.44.0/error_type.go, and sdk/log/logger.go to iteratively unwrap both *fmt.wrapError (fmt.Errorf with single %w) and single-error *errors.joinError (errors.Join when len(u.Unwrap()) == 1).
  • Preserve existing behavior when errors.Join wraps multiple non-nil errors (len > 1 continues to report *errors.joinError) and when custom user-defined error types implement Unwrap() []error (custom wrapper types continue to report their top-level concrete type, matching #8133 / #7975).

Alternatives Considered

  • Avoiding errors.Join at individual call sites inside opentelemetry-go: Only fixes internal call sites and leaves external instrumentation and callers using errors.Join(nil, err) reporting *errors.joinError. Handling single-error errors.Join alongside fmt.Errorf in semconv and sdk/log fixes this consistently across the ecosystem.
  • Unwrapping arbitrary Unwrap() []error implementations with len == 1: Rejected for the same reason #8133 / #7975 restricted single-error unwrapping to fmt.Errorf: user-defined domain error types implementing Unwrap() []error carry meaningful top-level type identity that should not be stripped.

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-11-09 20:47 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@dashpole
dashpole requested a balanced review from Copilot November 8, 2026 00:51
@dashpole
dashpole force-pushed the unwrap-single-errors-join branch from a285787 to f352674 Compare November 8, 2026 00:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@codecov

codecov Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.8%. Comparing base (63c5f44) to head (d543e05).

Files with missing lines Patch % Lines
semconv/v1.44.0/error_type.go 0.0% 13 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #9466     +/-   ##
=======================================
- Coverage   89.8%   89.8%   -0.1%     
=======================================
  Files        357     357             
  Lines      23965   23977     +12     
=======================================
+ Hits       21535   21541      +6     
- Misses      2430    2436      +6     
Files with missing lines Coverage Δ
sdk/log/logger.go 100.0% <100.0%> (ø)
semconv/v1.44.0/error_type.go 0.0% <0.0%> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dashpole
dashpole marked this pull request as ready for review November 8, 2026 01:13
@dmathieu
dmathieu requested a balanced review from Copilot November 9, 2026 08:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

There are no active review issues for the changes that derive meaningful error types through single-error join wrappers.

No open issues 🎉

Review effort: Balanced

@dashpole
dashpole force-pushed the unwrap-single-errors-join branch from f352674 to d543e05 Compare November 9, 2026 20:16
@opentelemetry-pr-dashboard
opentelemetry-pr-dashboard Bot requested a balanced review from Copilot November 9, 2026 20:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@pellared
pellared added this pull request to the merge queue Nov 9, 2026
Merged via the queue into open-telemetry:main with commit 1cf898e Nov 9, 2026
49 of 51 checks passed
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.

4 participants