Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: wrong type name used in UnmarshalTypeError #68941

Closed
j2gg0s opened this issue Aug 19, 2024 · 4 comments
Closed

encoding/json: wrong type name used in UnmarshalTypeError #68941

j2gg0s opened this issue Aug 19, 2024 · 4 comments
Labels
FixPending Issues that have a fix which has not yet been reviewed or submitted. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@j2gg0s
Copy link
Contributor

j2gg0s commented Aug 19, 2024

Go version

go version go1.22.4 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/j2gg0s/Library/Caches/go-build'
GOENV='/Users/j2gg0s/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/j2gg0s/go/pkg/mod'
GONOPROXY='dev.msh.team,ohai.bot,github.com/j2gg0s'
GONOSUMDB='dev.msh.team,ohai.bot,github.com/j2gg0s'
GOOS='darwin'
GOPATH='/Users/j2gg0s/go'
GOPRIVATE='dev.msh.team,ohai.bot,github.com/j2gg0s'
GOPROXY='https://goproxy.cn,direct'
GOROOT='/Users/j2gg0s/sdk/go1.22.4'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='go1.22.4'
GOTOOLDIR='/Users/j2gg0s/sdk/go1.22.4/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/j2gg0s/gosrc/src/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/3g/291pfdd54f11rlb15_hbq1dr0000gn/T/go-build1558397162=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

package main

import (
	"encoding/json"
	"fmt"
)

type Y struct {
	ZField int
}

type X struct {
	YField Y
}

func ExampleUnmarshalTypeError() {
	x := X{}
	if err := json.Unmarshal([]byte(`{"YField": {"ZField": "hello"}}`), &x); err != nil {
		fmt.Println(err)
	}
	// Output:
	// json: cannot unmarshal string into Go struct field Y.YField.ZField of type int
}

What did you see happen?

Error's message is json: cannot unmarshal string into Go struct field Y.YField.ZField of type int

What did you expect to see?

Error's message should bejson: cannot unmarshal string into Go struct field X.YField.ZField of type int

If my understanding is correct, can I submit a PR to fix this issue?

@seankhliao seankhliao changed the title encoding/json: UnmarshalTypeError's Struct is error when unmarshal nested struct. encoding/json: wrong type name used in UnmarshalTypeError Aug 19, 2024
@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 19, 2024
@j2gg0s
Copy link
Contributor Author

j2gg0s commented Aug 19, 2024

Additional information about the solution.

Can we insert the Struct as the first element of the Field and no longer maintain the Struct field.
decode.go#L123

// An UnmarshalTypeError describes a JSON value that was
// not appropriate for a value of a specific Go type.
type UnmarshalTypeError struct {
	Value  string       // description of JSON value - "bool", "array", "number -5"
	Type   reflect.Type // type of Go value it could not be assigned to
	Offset int64        // error occurred after reading Offset bytes
	Struct string       // name of the struct type containing the field
	Field  string       // the full path from root node to the field
}

j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 20, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 20, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/606956 mentions this issue: encoding/json: print correct field path in UnmarshalTypeError

j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 21, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 21, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 22, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 23, 2024
Use the outermost struct as the first element of the FieldStack,
so we can output the correct and complete field path.

In addition, add the embeded structure to the FieldStack.

Fixes golang#68941
j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 27, 2024
Including embedded struct inforamtion in error message.

Fixes golang#68941
@j2gg0s
Copy link
Contributor Author

j2gg0s commented Aug 27, 2024

At the same time, we also lose the embedded struct information.

package main

import (
	"encoding/json"
	"fmt"
)

type Y struct {
	ZField int
}

type X struct {
	YField Y
}

type A struct {
	IntField int
}
type B struct {
	A
}
type C struct {
	B
}

func ExampleUnmarshalTypeError() {
	x := X{}
	if err := json.Unmarshal([]byte(`{"YField": {"ZField": "hello"}}`), &x); err != nil {
		fmt.Println(err)
	}
	c := C{}
	if err := json.Unmarshal([]byte(`{"IntField": "hello"}`), &c); err != nil {
		fmt.Println(err)
	}
	// Output:
	// json: cannot unmarshal string into Go struct field Y.YField.ZField of type int
	// json: cannot unmarshal string into Go struct field C.IntField of type int
}

j2gg0s added a commit to j2gg0s/go that referenced this issue Aug 27, 2024
Including embedded struct inforamtion in error message.

Fixes golang#68941
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. FixPending Issues that have a fix which has not yet been reviewed or submitted. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Sep 3, 2024
@dmitshur dmitshur added this to the Go1.24 milestone Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FixPending Issues that have a fix which has not yet been reviewed or submitted. NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants