feat: add spancheck
linter (#4290)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
parent
0fdf33aaaa
commit
d23c35470b
@ -1912,6 +1912,24 @@ linters-settings:
|
|||||||
# Default: false
|
# Default: false
|
||||||
args-on-sep-lines: true
|
args-on-sep-lines: true
|
||||||
|
|
||||||
|
spancheck:
|
||||||
|
# Checks to enable.
|
||||||
|
# Options include:
|
||||||
|
# - `end`: check that `span.End()` is called
|
||||||
|
# - `record-error`: check that `span.RecordError(err)` is called when an error is returned
|
||||||
|
# - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned
|
||||||
|
# Default: ["end"]
|
||||||
|
checks:
|
||||||
|
- end
|
||||||
|
- record-error
|
||||||
|
- set-status
|
||||||
|
# A list of regexes for function signatures that silence `record-error` and `set-status` reports
|
||||||
|
# if found in the call path to a returned error.
|
||||||
|
# https://github.com/jjti/go-spancheck#ignore-check-signatures
|
||||||
|
# Default: []
|
||||||
|
ignore-check-signatures:
|
||||||
|
- "telemetry.RecordError"
|
||||||
|
|
||||||
staticcheck:
|
staticcheck:
|
||||||
# Deprecated: use the global `run.go` instead.
|
# Deprecated: use the global `run.go` instead.
|
||||||
go: "1.15"
|
go: "1.15"
|
||||||
@ -2442,6 +2460,7 @@ linters:
|
|||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
- scopelint
|
||||||
- sloglint
|
- sloglint
|
||||||
|
- spancheck
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
@ -2562,6 +2581,7 @@ linters:
|
|||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
- scopelint
|
||||||
- sloglint
|
- sloglint
|
||||||
|
- spancheck
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
|
1
go.mod
1
go.mod
@ -57,6 +57,7 @@ require (
|
|||||||
github.com/jgautheron/goconst v1.7.0
|
github.com/jgautheron/goconst v1.7.0
|
||||||
github.com/jingyugao/rowserrcheck v1.1.1
|
github.com/jingyugao/rowserrcheck v1.1.1
|
||||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af
|
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af
|
||||||
|
github.com/jjti/go-spancheck v0.4.2
|
||||||
github.com/julz/importas v0.1.0
|
github.com/julz/importas v0.1.0
|
||||||
github.com/kisielk/errcheck v1.6.3
|
github.com/kisielk/errcheck v1.6.3
|
||||||
github.com/kkHAIKE/contextcheck v1.1.4
|
github.com/kkHAIKE/contextcheck v1.1.4
|
||||||
|
2
go.sum
generated
2
go.sum
generated
@ -310,6 +310,8 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz
|
|||||||
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
|
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
|
||||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
|
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
|
||||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
|
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
|
||||||
|
github.com/jjti/go-spancheck v0.4.2 h1:4MvJOTKRi9ClsPNTxVhHvcSyuInILLSKmstTCJ/oIZI=
|
||||||
|
github.com/jjti/go-spancheck v0.4.2/go.mod h1:TBZ1nIcHTtCnBChHcjd+5agCxHBaW0tzw9quzCCNAts=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
@ -245,13 +245,14 @@ type LintersSettings struct {
|
|||||||
Revive ReviveSettings
|
Revive ReviveSettings
|
||||||
RowsErrCheck RowsErrCheckSettings
|
RowsErrCheck RowsErrCheckSettings
|
||||||
SlogLint SlogLintSettings
|
SlogLint SlogLintSettings
|
||||||
|
Spancheck SpancheckSettings
|
||||||
Staticcheck StaticCheckSettings
|
Staticcheck StaticCheckSettings
|
||||||
Structcheck StructCheckSettings
|
Structcheck StructCheckSettings
|
||||||
Stylecheck StaticCheckSettings
|
Stylecheck StaticCheckSettings
|
||||||
TagAlign TagAlignSettings
|
TagAlign TagAlignSettings
|
||||||
Tagliatelle TagliatelleSettings
|
Tagliatelle TagliatelleSettings
|
||||||
Testifylint TestifylintSettings
|
|
||||||
Tenv TenvSettings
|
Tenv TenvSettings
|
||||||
|
Testifylint TestifylintSettings
|
||||||
Testpackage TestpackageSettings
|
Testpackage TestpackageSettings
|
||||||
Thelper ThelperSettings
|
Thelper ThelperSettings
|
||||||
Unparam UnparamSettings
|
Unparam UnparamSettings
|
||||||
@ -773,6 +774,11 @@ type SlogLintSettings struct {
|
|||||||
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
|
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SpancheckSettings struct {
|
||||||
|
Checks []string `mapstructure:"checks"`
|
||||||
|
IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"`
|
||||||
|
}
|
||||||
|
|
||||||
type StaticCheckSettings struct {
|
type StaticCheckSettings struct {
|
||||||
// Deprecated: use the global `run.go` instead.
|
// Deprecated: use the global `run.go` instead.
|
||||||
GoVersion string `mapstructure:"go"`
|
GoVersion string `mapstructure:"go"`
|
||||||
|
29
pkg/golinters/spancheck.go
Normal file
29
pkg/golinters/spancheck.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jjti/go-spancheck"
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
|
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewSpancheck(settings *config.SpancheckSettings) *goanalysis.Linter {
|
||||||
|
cfg := spancheck.NewDefaultConfig()
|
||||||
|
|
||||||
|
if settings != nil {
|
||||||
|
if settings.Checks != nil {
|
||||||
|
cfg.EnabledChecks = settings.Checks
|
||||||
|
}
|
||||||
|
|
||||||
|
if settings.IgnoreCheckSignatures != nil {
|
||||||
|
cfg.IgnoreChecksSignaturesSlice = settings.IgnoreCheckSignatures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a := spancheck.NewAnalyzerWithConfig(cfg)
|
||||||
|
|
||||||
|
return goanalysis.
|
||||||
|
NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
|
||||||
|
WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||||
|
}
|
@ -131,6 +131,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
reviveCfg *config.ReviveSettings
|
reviveCfg *config.ReviveSettings
|
||||||
rowserrcheckCfg *config.RowsErrCheckSettings
|
rowserrcheckCfg *config.RowsErrCheckSettings
|
||||||
sloglintCfg *config.SlogLintSettings
|
sloglintCfg *config.SlogLintSettings
|
||||||
|
spancheckCfg *config.SpancheckSettings
|
||||||
staticcheckCfg *config.StaticCheckSettings
|
staticcheckCfg *config.StaticCheckSettings
|
||||||
structcheckCfg *config.StructCheckSettings
|
structcheckCfg *config.StructCheckSettings
|
||||||
stylecheckCfg *config.StaticCheckSettings
|
stylecheckCfg *config.StaticCheckSettings
|
||||||
@ -216,6 +217,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
reviveCfg = &m.cfg.LintersSettings.Revive
|
reviveCfg = &m.cfg.LintersSettings.Revive
|
||||||
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
|
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
|
||||||
sloglintCfg = &m.cfg.LintersSettings.SlogLint
|
sloglintCfg = &m.cfg.LintersSettings.SlogLint
|
||||||
|
spancheckCfg = &m.cfg.LintersSettings.Spancheck
|
||||||
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
||||||
structcheckCfg = &m.cfg.LintersSettings.Structcheck
|
structcheckCfg = &m.cfg.LintersSettings.Structcheck
|
||||||
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
||||||
@ -782,6 +784,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
WithLoadForGoAnalysis().
|
WithLoadForGoAnalysis().
|
||||||
WithURL("https://github.com/ryanrolds/sqlclosecheck"),
|
WithURL("https://github.com/ryanrolds/sqlclosecheck"),
|
||||||
|
|
||||||
|
linter.NewConfig(golinters.NewSpancheck(spancheckCfg)).
|
||||||
|
WithSince("v1.56.0").
|
||||||
|
WithLoadForGoAnalysis().
|
||||||
|
WithPresets(linter.PresetBugs).
|
||||||
|
WithURL("https://github.com/jjti/go-spancheck"),
|
||||||
|
|
||||||
linter.NewConfig(golinters.NewStaticcheck(staticcheckCfg)).
|
linter.NewConfig(golinters.NewStaticcheck(staticcheckCfg)).
|
||||||
WithEnabledByDefault().
|
WithEnabledByDefault().
|
||||||
WithSince("v1.0.0").
|
WithSince("v1.0.0").
|
||||||
|
@ -33,6 +33,7 @@ func TestSourcesFromTestdataSubDir(t *testing.T) {
|
|||||||
"ginkgolinter",
|
"ginkgolinter",
|
||||||
"zerologlint",
|
"zerologlint",
|
||||||
"protogetter",
|
"protogetter",
|
||||||
|
"spancheck",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range subDirs {
|
for _, dir := range subDirs {
|
||||||
|
8
test/testdata/spancheck/configs/enable_all.yml
vendored
Normal file
8
test/testdata/spancheck/configs/enable_all.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
linters-settings:
|
||||||
|
spancheck:
|
||||||
|
checks:
|
||||||
|
- "end"
|
||||||
|
- "record-error"
|
||||||
|
- "set-status"
|
||||||
|
ignore-check-signatures:
|
||||||
|
- "recordErr"
|
14
test/testdata/spancheck/go.mod
vendored
Normal file
14
test/testdata/spancheck/go.mod
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module spancheck
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
go.opentelemetry.io/otel v1.21.0
|
||||||
|
go.opentelemetry.io/otel/trace v1.21.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-logr/logr v1.4.1 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||||
|
)
|
16
test/testdata/spancheck/go.sum
generated
vendored
Normal file
16
test/testdata/spancheck/go.sum
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||||
|
github.com/go-logr/logr v1.4.1/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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||||
|
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||||
|
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||||
|
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||||
|
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||||
|
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
90
test/testdata/spancheck/spancheck_default.go
vendored
Normal file
90
test/testdata/spancheck/spancheck_default.go
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//golangcitest:args -Espancheck
|
||||||
|
package spancheck
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testDefaultError struct{}
|
||||||
|
|
||||||
|
func (e *testDefaultError) Error() string {
|
||||||
|
return "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
// incorrect
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak"
|
||||||
|
ctx, _ := otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak"
|
||||||
|
fmt.Print(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
ctx, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
print(ctx.Done(), span.IsRecording())
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
var ctx, span = otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
print(ctx.Done(), span.IsRecording())
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
_, span = otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
fmt.Print(span)
|
||||||
|
defer span.End()
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
// correct
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if false {
|
||||||
|
err := errors.New("foo")
|
||||||
|
span.SetStatus(codes.Error, err.Error())
|
||||||
|
span.RecordError(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.SetStatus(codes.Error, "foo")
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return errors.New("bar")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
_, span = otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
}
|
206
test/testdata/spancheck/spancheck_enable_all.go
vendored
Normal file
206
test/testdata/spancheck/spancheck_enable_all.go
vendored
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
//golangcitest:config_path configs/enable_all.yml
|
||||||
|
//golangcitest:args -Espancheck
|
||||||
|
package spancheck
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/codes"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testError struct{}
|
||||||
|
|
||||||
|
func (e *testError) Error() string {
|
||||||
|
return "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
// incorrect
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak"
|
||||||
|
ctx, _ := otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak"
|
||||||
|
fmt.Print(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
ctx, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
print(ctx.Done(), span.IsRecording())
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
var ctx, span = otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
print(ctx.Done(), span.IsRecording())
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak"
|
||||||
|
_, span = otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
fmt.Print(span)
|
||||||
|
defer span.End()
|
||||||
|
} // want "return can be reached without calling span.End"
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
err := errors.New("foo")
|
||||||
|
span.RecordError(err)
|
||||||
|
return err // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return errors.New("foo") // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return &testError{} // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.RecordError is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.SetStatus(codes.Error, "foo")
|
||||||
|
return &testError{} // want "return can be reached without calling span.RecordError"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() (string, error) {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return "", &testError{} // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() (string, error) {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return "", errors.New("foo") // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
f := func() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return errors.New("foo") // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fmt.Println(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths"
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
{
|
||||||
|
if true {
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return errors.New("foo") // want "return can be reached without calling span.SetStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// correct
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if true {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if false {
|
||||||
|
err := errors.New("foo")
|
||||||
|
span.SetStatus(codes.Error, err.Error())
|
||||||
|
span.RecordError(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if true {
|
||||||
|
span.SetStatus(codes.Error, "foo")
|
||||||
|
span.RecordError(errors.New("foo"))
|
||||||
|
return errors.New("bar")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
_, span = otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore error because of matching func sig
|
||||||
|
func _() error {
|
||||||
|
_, span := otel.Tracer("foo").Start(context.Background(), "bar")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
err := errors.New("foo")
|
||||||
|
recordError(span, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func recordError(span trace.Span, err error) {}
|
Loading…
x
Reference in New Issue
Block a user