Make sure flagValue.String() can be called even when flagValue is created by reflect.New (#11651)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description
Make sure `flagValue.String()` can be called even when flagValue is
created by `reflect.New`
```go
import (
"flag"
"log"
"go.opentelemetry.io/collector/featuregate"
)
func main() {
fs := new(flag.FlagSet)
featuregate.GlobalRegistry().RegisterFlags(fs)
if err := fs.Parse([]string{"--help"}); err != nil {
log.Fatalf("failed to parse flags: %v", err)
}
}
```
Before this PR
```
Usage:
-feature-gates value
Comma-delimited list of feature gate identifiers. Prefix with '-' to disable the feature. '+' or no prefix will enable the feature.
panic calling String method on zero featuregate.flagValue for flag feature-gates: runtime error: invalid memory address or nil pointer dereference
failed to parse flags: flag: help requested
```
Note that there is a panic in the message.
After this PR
```
Usage:
-feature-gates value
Comma-delimited list of feature gate identifiers. Prefix with '-' to disable the feature. '+' or no prefix will enable the feature.
failed to parse flags: flag: help requested
```
---------
Co-authored-by: Yang Song <songy23@users.noreply.github.com>
This commit is contained in:
parent
63c7fece02
commit
16ab931966
|
|
@ -0,0 +1,25 @@
|
|||
# Use this changelog template to create an entry for release notes.
|
||||
|
||||
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
|
||||
change_type: bug_fix
|
||||
|
||||
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
|
||||
component: featuregate
|
||||
|
||||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
|
||||
note: Fix an unfriendly display message `runtime error` when featuregate is used to display command line usage.
|
||||
|
||||
# One or more tracking issues or pull requests related to the change
|
||||
issues: [11651]
|
||||
|
||||
# (Optional) One or more lines of additional information to render under the primary note.
|
||||
# These lines will be padded with 2 spaces and then inserted directly into the document.
|
||||
# Use pipe (|) for multiline entries.
|
||||
subtext:
|
||||
|
||||
# Optional: The change log or logs in which this entry should be included.
|
||||
# e.g. '[user]' or '[user, api]'
|
||||
# Include 'user' if the change is relevant to end users.
|
||||
# Include 'api' if there is a change to a library API.
|
||||
# Default: '[user]'
|
||||
change_logs: [user]
|
||||
|
|
@ -31,6 +31,12 @@ type flagValue struct {
|
|||
}
|
||||
|
||||
func (f *flagValue) String() string {
|
||||
// This function can be called by isZeroValue https://github.com/golang/go/blob/go1.23.3/src/flag/flag.go#L630
|
||||
// which creates an instance of flagValue using reflect.New. In this case, the field `reg` is nil.
|
||||
if f.reg == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var ids []string
|
||||
f.reg.VisitAll(func(g *Gate) {
|
||||
id := g.ID()
|
||||
|
|
|
|||
|
|
@ -132,3 +132,8 @@ func TestNewFlag(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagStringNotInitialize(t *testing.T) {
|
||||
flag := &flagValue{}
|
||||
assert.Empty(t, flag.String())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue