improve JSON error message (#5412) (#5433)

Co-authored-by: Zaphkiel <duambi123@gmail.com>
This commit is contained in:
Alessandro Ros
2026-02-07 19:52:27 +01:00
committed by GitHub
co-authored by Zaphkiel
parent 0f6e61f5af
commit 4a559338ae
2 changed files with 37 additions and 14 deletions
+10 -3
View File
@@ -15,10 +15,13 @@ import (
// - prevents using existing elements of slices, fixing https://github.com/golang/go/issues/21092
// - prevents setting slices to nil
func process(v reflect.Value, raw any) error {
func process(v reflect.Value, raw any, path string) error {
switch v.Kind() {
case reflect.Slice:
if raw == nil {
if path != "" {
return fmt.Errorf("cannot set slice '%s' to nil", path)
}
return fmt.Errorf("cannot set slice to nil")
}
@@ -41,7 +44,11 @@ func process(v reflect.Value, raw any) error {
jsonKey = strings.Split(jsonKey, ",")[0]
if rawVal, ok2 := rawMap[jsonKey]; ok2 {
err := process(field, rawVal)
fieldPath := jsonKey
if path != "" {
fieldPath = path + "." + jsonKey
}
err := process(field, rawVal, fieldPath)
if err != nil {
return err
}
@@ -71,7 +78,7 @@ func Decode(r io.Reader, dest any) error {
return err
}
err = process(reflect.ValueOf(dest).Elem(), raw)
err = process(reflect.ValueOf(dest).Elem(), raw, "")
if err != nil {
return err
}
+27 -11
View File
@@ -74,21 +74,37 @@ func TestUnmarshalPreventSliceReuse(t *testing.T) {
}
func TestUnmarshalSetSliceToNil(t *testing.T) {
type Data struct {
Items []string `json:"items"`
}
t.Run("top level", func(t *testing.T) {
type Data struct {
Items []string `json:"items"`
}
var data Data
var data Data
json := []byte(`{"items": null}`)
err := Unmarshal(json, &data)
require.EqualError(t, err, "cannot set slice to nil")
json := []byte(`{"items": null}`)
err := Unmarshal(json, &data)
require.EqualError(t, err, "cannot set slice 'items' to nil")
data = Data{Items: []string{"a", "b"}}
data = Data{Items: []string{"a", "b"}}
json = []byte(`{"items": null}`)
err = Unmarshal(json, &data)
require.EqualError(t, err, "cannot set slice to nil")
json = []byte(`{"items": null}`)
err = Unmarshal(json, &data)
require.EqualError(t, err, "cannot set slice 'items' to nil")
})
t.Run("nested", func(t *testing.T) {
type Inner struct {
Values []int `json:"values"`
}
type Outer struct {
Inner Inner `json:"inner"`
}
var data Outer
json := []byte(`{"inner": {"values": null}}`)
err := Unmarshal(json, &data)
require.EqualError(t, err, "cannot set slice 'inner.values' to nil")
})
}
func TestUnmarshalSetNullableSliceToNil(t *testing.T) {