Skip to content

Commit

Permalink
Make the AsType functions not panic (#3489)
Browse files Browse the repository at this point in the history
* Make the AsType functions not panic

* Adds changelog

Signed-off-by: Aaron Clawson <[email protected]>

Signed-off-by: Aaron Clawson <[email protected]>
Co-authored-by: Chester Cheung <[email protected]>
  • Loading branch information
MadVikingGod and hanyuancheung authored Nov 25, 2022
1 parent 1f5e6ad commit d7b3115
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggragation. (#3408)
- Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432)
- Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440)
- Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489)

## Removed

Expand Down
48 changes: 48 additions & 0 deletions attribute/kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"

"go.opentelemetry.io/otel/attribute"
)
Expand Down Expand Up @@ -132,3 +133,50 @@ func TestKeyValueValid(t *testing.T) {
}
}
}

func TestIncorrectCast(t *testing.T) {
testCases := []struct {
name string
val attribute.Value
}{
{
name: "Float64",
val: attribute.Float64Value(1.0),
},
{
name: "Int64",
val: attribute.Int64Value(2),
},
{
name: "String",
val: attribute.BoolValue(true),
},
{
name: "Float64Slice",
val: attribute.Float64SliceValue([]float64{1.0}),
},
{
name: "Int64Slice",
val: attribute.Int64SliceValue([]int64{2}),
},
{
name: "StringSlice",
val: attribute.BoolSliceValue([]bool{true}),
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
assert.NotPanics(t, func() {
tt.val.AsBool()
tt.val.AsBoolSlice()
tt.val.AsFloat64()
tt.val.AsFloat64Slice()
tt.val.AsInt64()
tt.val.AsInt64Slice()
tt.val.AsInterface()
tt.val.AsString()
tt.val.AsStringSlice()
})
})
}
}
44 changes: 36 additions & 8 deletions attribute/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ func (v Value) AsBool() bool {
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
// BOOLSLICE.
func (v Value) AsBoolSlice() []bool {
if v.vtype != BOOLSLICE {
return nil
}
return v.asBoolSlice()
}

func (v Value) asBoolSlice() []bool {
return attribute.AsSlice[bool](v.slice)
}

Expand All @@ -154,6 +161,13 @@ func (v Value) AsInt64() int64 {
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
// INT64SLICE.
func (v Value) AsInt64Slice() []int64 {
if v.vtype != INT64SLICE {
return nil
}
return v.asInt64Slice()
}

func (v Value) asInt64Slice() []int64 {
return attribute.AsSlice[int64](v.slice)
}

Expand All @@ -166,6 +180,13 @@ func (v Value) AsFloat64() float64 {
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is
// FLOAT64SLICE.
func (v Value) AsFloat64Slice() []float64 {
if v.vtype != FLOAT64SLICE {
return nil
}
return v.asFloat64Slice()
}

func (v Value) asFloat64Slice() []float64 {
return attribute.AsSlice[float64](v.slice)
}

Expand All @@ -178,6 +199,13 @@ func (v Value) AsString() string {
// AsStringSlice returns the []string value. Make sure that the Value's type is
// STRINGSLICE.
func (v Value) AsStringSlice() []string {
if v.vtype != STRINGSLICE {
return nil
}
return v.asStringSlice()
}

func (v Value) asStringSlice() []string {
return attribute.AsSlice[string](v.slice)
}

Expand All @@ -189,19 +217,19 @@ func (v Value) AsInterface() interface{} {
case BOOL:
return v.AsBool()
case BOOLSLICE:
return v.AsBoolSlice()
return v.asBoolSlice()
case INT64:
return v.AsInt64()
case INT64SLICE:
return v.AsInt64Slice()
return v.asInt64Slice()
case FLOAT64:
return v.AsFloat64()
case FLOAT64SLICE:
return v.AsFloat64Slice()
return v.asFloat64Slice()
case STRING:
return v.stringly
case STRINGSLICE:
return v.AsStringSlice()
return v.asStringSlice()
}
return unknownValueType{}
}
Expand All @@ -210,19 +238,19 @@ func (v Value) AsInterface() interface{} {
func (v Value) Emit() string {
switch v.Type() {
case BOOLSLICE:
return fmt.Sprint(v.AsBoolSlice())
return fmt.Sprint(v.asBoolSlice())
case BOOL:
return strconv.FormatBool(v.AsBool())
case INT64SLICE:
return fmt.Sprint(v.AsInt64Slice())
return fmt.Sprint(v.asInt64Slice())
case INT64:
return strconv.FormatInt(v.AsInt64(), 10)
case FLOAT64SLICE:
return fmt.Sprint(v.AsFloat64Slice())
return fmt.Sprint(v.asFloat64Slice())
case FLOAT64:
return fmt.Sprint(v.AsFloat64())
case STRINGSLICE:
return fmt.Sprint(v.AsStringSlice())
return fmt.Sprint(v.asStringSlice())
case STRING:
return v.stringly
default:
Expand Down

0 comments on commit d7b3115

Please sign in to comment.