Exemplo
go.opentelemetry.io/otel v1.45.0: BatchSpanProcessor and TracerProvider silently swallow and discard SpanExporter shutdown errors prior to v1.44.0 instead of propagating them to the caller
Amostra verificada para golang go.opentelemetry.io/otel v1.45.0: BatchSpanProcessor and TracerProvider silently swallow and discard SpanExporter shutdown…
sha256:857b0f9544f5c94ae1950b7dd9d735991244aeea14417acbc0dbd6c17a008fad
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 3
- Chaves de assinatura que o compilaram
- 2
Ambiente declarado
go linux x64 go go gomod
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| go 1.26 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-16 |
| go 1.26 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-18 |
| go 1.26 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | FAIL | compile:SKIPPED · contract:FAIL · load:SKIPPED · resolve:PASS CONTAINER_RUN · golang@1golang:1.26-alpine@sha256:28d89ee9cc0f… |
2026-09-07 |
Caso
HOW- Objetivo
- BatchSpanProcessor and TracerProvider silently swallow and discard SpanExporter shutdown errors prior to v1.44.0 instead of propagating them to the caller
- Símbolos
-
- go.opentelemetry.io/otel/sdk/trace.NewBatchSpanProcessor
- go.opentelemetry.io/otel/sdk/trace.WithBatcher
- go.opentelemetry.io/otel/sdk/trace.NewTracerProvider
- go.opentelemetry.io/otel/sdk/trace.SpanExporter
- Ambiente
- go
- Criado
- 2026-08-16T07:29:19Z
Contrato
- assert BatchSpanProcessor.Shutdown returns error matching underlying SpanExporter.Shutdown error
- assert TracerProvider.Shutdown with WithBatcher returns error matching underlying SpanExporter.Shutdown error
- assert BatchSpanProcessor and TracerProvider return nil error on clean exporter shutdown
Arquivos
- NOTES.md
- csx.json
- go.mod
- go.sum
- shutdown_test.go
Código-fonte
`search_known_solution` found sample `sha256:3f14ed288a161c7b18e8a641230a1acbbe95a6630bf2bfe7bf77cc02b2958d34` ("Unwired OpenTelemetry tracers silently emit invalid zero-context spans while batch-buffered tracers drop spans without explicit flush or shutdown").
A model would assume `BatchSpanProcessor.Shutdown` and `TracerProvider.Shutdown` always surface underlying `SpanExporter.Shutdown` errors when flushing and closing export pipelines.
The wrong version (v1.43.0 and earlier) fails silently with a green build: `bsp.Shutdown` and `tp.Shutdown` discard errors returned by `SpanExporter.Shutdown` and return `nil`, masking exporter shutdown failures while telemetry is dropped.
{"case":{"caseId":"case:sha256:9ac52a7c8a3ded16cbaf1dcf5a08270464a96a2b5cb04d065a1cadce0d889381","contract":["assert BatchSpanProcessor.Shutdown returns error matching underlying SpanExporter.Shutdown error","assert TracerProvider.Shutdown with WithBatcher returns error matching underlying SpanExporter.Shutdown error","assert BatchSpanProcessor and TracerProvider return nil error on clean exporter shutdown"],"goal":"BatchSpanProcessor and TracerProvider silently swallow and discard SpanExporter shutdown errors prior to v1.44.0 instead of propagating them to the caller","kind":"HOW","packages":["pkg:golang/go.opentelemetry.io/otel@v1.45.0","pkg:golang/go.opentelemetry.io/otel/sdk@v1.45.0"],"schemaVersion":1,"symbols":["go.opentelemetry.io/otel/sdk/trace.NewBatchSpanProcessor","go.opentelemetry.io/otel/sdk/trace.WithBatcher","go.opentelemetry.io/otel/sdk/trace.NewTracerProvider","go.opentelemetry.io/otel/sdk/trace.SpanExporter"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","ecosystem":"golang","executionContext":"go","language":"go","os":"linux","packageManager":"gomod","runtime":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/go.opentelemetry.io/otel@v1.45.0","pkg:golang/go.opentelemetry.io/otel/sdk@v1.45.0"],"schemaVersion":1,"symbols":["go.opentelemetry.io/otel/sdk/trace.NewBatchSpanProcessor","go.opentelemetry.io/otel/sdk/trace.WithBatcher","go.opentelemetry.io/otel/sdk/trace.NewTracerProvider","go.opentelemetry.io/otel/sdk/trace.SpanExporter"],"verifierAdapter":"golang@1"}
module sample
go 1.26.5
require (
go.opentelemetry.io/otel v1.45.0
go.opentelemetry.io/otel/sdk v1.45.0
)
require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/metric v1.45.0 // indirect
go.opentelemetry.io/otel/trace v1.45.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package sample_test
import (
"context"
"errors"
"testing"
"go.opentelemetry.io/otel"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
)
// faultyExporter embeds InMemoryExporter and returns a configurable error on Shutdown.
type faultyExporter struct {
*tracetest.InMemoryExporter
shutdownErr error
}
func (f *faultyExporter) Shutdown(ctx context.Context) error {
_ = f.InMemoryExporter.Shutdown(ctx)
return f.shutdownErr
}
func TestBatchSpanProcessorPropagatesExporterShutdownError(t *testing.T) {
ctx := context.Background()
exporterErr := errors.New("remote otlp export backend failed to close")
exporter := &faultyExporter{
InMemoryExporter: tracetest.NewInMemoryExporter(),
shutdownErr: exporterErr,
}
bsp := sdktrace.NewBatchSpanProcessor(exporter)
err := bsp.Shutdown(ctx)
if err == nil {
t.Fatalf("expected bsp.Shutdown to return error from faulty exporter, got nil")
}
if !errors.Is(err, exporterErr) {
t.Fatalf("expected error wrapping %v, got %v", exporterErr, err)
}
}
func TestTracerProviderBatcherPropagatesExporterShutdownError(t *testing.T) {
ctx := context.Background()
exporterErr := errors.New("backend connection lost during flush")
exporter := &faultyExporter{
InMemoryExporter: tracetest.NewInMemoryExporter(),
shutdownErr: exporterErr,
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(tp)
tr := otel.Tracer("shutdown-test")
_, span := tr.Start(ctx, "test-op")
span.End()
err := tp.Shutdown(ctx)
if err == nil {
t.Fatalf("expected tp.Shutdown with batcher to return exporter shutdown error, got nil")
}
if !errors.Is(err, exporterErr) {
t.Fatalf("expected error wrapping %v, got %v", exporterErr, err)
}
}
func TestBatcherCleanShutdownReturnsNil(t *testing.T) {
ctx := context.Background()
exporter := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
)
tr := tp.Tracer("clean-shutdown-test")
_, span := tr.Start(ctx, "clean-op")
span.End()
if err := tp.Shutdown(ctx); err != nil {
t.Fatalf("expected clean shutdown to succeed with nil error, got: %v", err)
}
}