Skip to content

Commit

Permalink
Merge pull request #225 from bugsnag/next
Browse files Browse the repository at this point in the history
## 2.3.1 (2024-03-18)

### Bug fixes

* Handle empty pointers to complex structs in metadata.Add
  [#221](#221)
  • Loading branch information
DariaKunoichi authored Mar 18, 2024
2 parents b245ac8 + d8cca0e commit c17eb96
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 17 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2.3.1 (2024-03-18)

### Bug fixes

* Handle empty pointers to complex structs in metadata.Add
[#221](https://github.com/bugsnag/bugsnag-go/pull/221)

## 2.3.0 (2024-03-05)

### Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion v2/bugsnag.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

// Version defines the version of this Bugsnag notifier
const Version = "2.3.0"
const Version = "2.3.1"

var panicHandlerOnce sync.Once
var sessionTrackerOnce sync.Once
Expand Down
35 changes: 19 additions & 16 deletions v2/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (meta MetaData) AddStruct(tab string, obj interface{}) {
meta[tab] = content
} else {
// Wasn't a struct
meta.Add("Extra data", tab, obj)
meta.Add("Extra data", tab, val)
}

}
Expand Down Expand Up @@ -84,32 +84,38 @@ func (s sanitizer) Sanitize(data interface{}) interface{} {
// Sanitizers are passed by value, so we can modify s and it only affects
// s.Seen for nested calls.
s.Seen = append(s.Seen, data)
t := reflect.TypeOf(data)
v := reflect.ValueOf(data)

if t == nil {
return "<nil>"
}

// Handle nil pointers and interfaces specifically
if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
if v.IsNil() {
return "<nil>"
}
}

// Handle certain well known interfaces and types
switch data := data.(type) {
switch dataT := data.(type) {
case error:
return data.Error()
return dataT.Error()

case time.Time:
return data.Format(time.RFC3339Nano)
return dataT.Format(time.RFC3339Nano)

case fmt.Stringer:
// This also covers time.Duration
return data.String()
return dataT.String()

case encoding.TextMarshaler:
if b, err := data.MarshalText(); err == nil {
if b, err := dataT.MarshalText(); err == nil {
return string(b)
}
}

t := reflect.TypeOf(data)
v := reflect.ValueOf(data)

if t == nil {
return "<nil>"
}

switch t.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
Expand All @@ -121,9 +127,6 @@ func (s sanitizer) Sanitize(data interface{}) interface{} {
return data

case reflect.Interface, reflect.Ptr:
if v.IsNil() {
return "<nil>"
}
return s.Sanitize(v.Elem().Interface())

case reflect.Array, reflect.Slice:
Expand Down
80 changes: 80 additions & 0 deletions v2/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ func (_textMarshaller) MarshalText() ([]byte, error) {
return []byte("marshalled text"), nil
}

type _testStringer struct{}

func (s _testStringer) String() string {
return "something"
}

type _testError struct{}

func (s _testError) Error() string {
return "errorstr"
}

type _testStruct struct {
Name *_testStringer
}

var account = _account{}
var notifier = New(Configuration{})

Expand Down Expand Up @@ -77,6 +93,70 @@ func TestMetaDataAdd(t *testing.T) {
}
}

func TestMetadataAddPointer(t *testing.T) {
var pointer *_testStringer
md := MetaData{}
md.AddStruct("emptypointer", pointer)
fullPointer := &_testStringer{}
md.AddStruct("fullpointer", fullPointer)

if !reflect.DeepEqual(md, MetaData{
"Extra data": {
"emptypointer": "<nil>",
"fullpointer": "something",
},
}) {
t.Errorf("metadata.AddStruct didn't work: %#v", md)
}
}

func TestMetadataAddNil(t *testing.T) {
md := MetaData{}
md.AddStruct("map", map[string]interface{}{
"data": _testStruct{Name: nil},
})

var nilMap map[string]interface{}
md.AddStruct("nilmap", nilMap)

var nilError _testError
md.AddStruct("error", nilError)

var nilErrorPtr *_testError
md.AddStruct("errorNilPtr", nilErrorPtr)

var timeVar time.Time
md.AddStruct("timeUnset", timeVar)

var duration time.Duration
md.AddStruct("durationUnset", duration)

var marshalNilPtr *_textMarshaller
md.AddStruct("marshalNilPtr", marshalNilPtr)

var marshalFullPtr = &_textMarshaller{}
md.AddStruct("marshalFullPtr", marshalFullPtr)

if !reflect.DeepEqual(md, MetaData{
"map": {
"data": map[string]interface{}{
"Name": "<nil>",
},
},
"nilmap": map[string]interface{}{},
"Extra data": {
"error": "errorstr",
"errorNilPtr": "<nil>",
"timeUnset": "0001-01-01T00:00:00Z",
"durationUnset": "0s",
"marshalFullPtr": "marshalled text",
"marshalNilPtr": "<nil>",
},
}) {
t.Errorf("metadata.AddStruct didn't work: %#v", md)
}
}

func TestMetaDataUpdate(t *testing.T) {

m := MetaData{
Expand Down

0 comments on commit c17eb96

Please sign in to comment.