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

Error when marshalling a structure with a field being an interface #13

Open
ziemekobel-ef opened this issue Oct 5, 2023 · 4 comments
Open

Comments

@ziemekobel-ef
Copy link

When trying to marshal a structure that has a field declared as an interface, an error gets returned.
Tested using Go 1.21, MacOS 14.0, M1 Pro.

The following test demonstrates it:

package lib

import (
	"testing"

	"github.com/wI2L/jettison"
)

type Circle struct {
	Radius int `json:"radius"`
}

func (c Circle) Area() int {
	return c.Radius * c.Radius
}

type Shape interface {
	Area() int
}

type Foo struct {
	S Shape `json:"s"`
}

func TestJettisonMarshal(t *testing.T) {
	foo := Foo{S: Circle{Radius: 1}}

	_, err := jettison.Marshal(foo)
	if err != nil {
		t.Fatal(err)
	}
}

returns:

=== RUN   TestJettisonMarshal
runtime: nameOff 0x2af780 out of range 0x10029c000 - 0x1002d5a08
fatal error: runtime: name offset out of range

goroutine 6 [running]:
runtime.throw({0x1002704f4?, 0x14000003ba0?})
	/usr/local/go/src/runtime/panic.go:1077 +0x40 fp=0x14000125570 sp=0x14000125540 pc=0x1001994c0
runtime.resolveNameOff(0x14000125608?, 0x2af780)
	/usr/local/go/src/runtime/type.go:119 +0x214 fp=0x140001255d0 sp=0x14000125570 pc=0x1001c2f04
reflect.resolveNameOff(0x1400000e101?, 0x2d3f48?)
	/usr/local/go/src/runtime/runtime1.go:604 +0x1c fp=0x140001255f0 sp=0x140001255d0 pc=0x1001c8b1c
reflect.(*rtype).nameOff(...)
	/usr/local/go/src/reflect/type.go:526
reflect.(*rtype).String(0x1002d3f48)
	/usr/local/go/src/reflect/type.go:542 +0x24 fp=0x14000125610 sp=0x140001255f0 pc=0x1001fa964
fmt.(*pp).handleMethods(0x1400007ad00, 0x418108?)
	/usr/local/go/src/fmt/print.go:673 +0x21c fp=0x14000125870 sp=0x14000125610 pc=0x100206b9c
fmt.(*pp).printArg(0x1400007ad00, {0x1002ce3c0?, 0x1002d3f48}, 0x73)
	/usr/local/go/src/fmt/print.go:756 +0x5fc fp=0x14000125910 sp=0x14000125870 pc=0x1002075cc
fmt.(*pp).doPrintf(0x1400007ad00, {0x10026e5ea, 0x1a}, {0x14000125ab8?, 0x1, 0x1})
	/usr/local/go/src/fmt/print.go:1077 +0x2dc fp=0x14000125a20 sp=0x14000125910 pc=0x100209dcc
fmt.Sprintf({0x10026e5ea, 0x1a}, {0x14000125ab8, 0x1, 0x1})
	/usr/local/go/src/fmt/print.go:239 +0x4c fp=0x14000125a80 sp=0x14000125a20 pc=0x10020462c
github.com/wI2L/jettison.(*UnsupportedTypeError).Error(0x1002d5701?)
	/Users/ziemekobel/go/pkg/mod/github.com/w!i2!l/[email protected]/json.go:67 +0x50 fp=0x14000125ad0 sp=0x14000125a80 pc=0x100264060
fmt.(*pp).handleMethods(0x1400007a9c0, 0x0?)
	/usr/local/go/src/fmt/print.go:667 +0x158 fp=0x14000125d30 sp=0x14000125ad0 pc=0x100206ad8
fmt.(*pp).printArg(0x1400007a9c0, {0x1002b03e0?, 0x140000242b0}, 0x76)
	/usr/local/go/src/fmt/print.go:756 +0x5fc fp=0x14000125dd0 sp=0x14000125d30 pc=0x1002075cc
fmt.(*pp).doPrintln(0x1400007a9c0, {0x14000125f48?, 0x1, 0x14000024220?})
	/usr/local/go/src/fmt/print.go:1223 +0x3c fp=0x14000125e50 sp=0x14000125dd0 pc=0x10020acfc
fmt.Sprintln({0x14000125f48, 0x1, 0x1})
	/usr/local/go/src/fmt/print.go:321 +0x3c fp=0x14000125ea0 sp=0x14000125e50 pc=0x10020489c
testing.(*common).Fatal(0x14000003a00, {0x14000125f48?, 0x14000073f48?, 0x1001de19c?})
	/usr/local/go/src/testing/testing.go:1075 +0x3c fp=0x14000125f00 sp=0x14000125ea0 pc=0x10021f75c
ef-studio/catalyst/tests/lib.TestJettisonMarshal(0x14000003a00)
	/Users/ziemekobel/ws/ef-studio/backend/go/catalyst/tests/lib/jettison_test.go:30 +0x94 fp=0x14000125f60 sp=0x14000125f00 pc=0x100268bd4
@wI2L
Copy link
Owner

wI2L commented Oct 6, 2023

@ziemekobel-ef Can reproduce, but after a bit of digging, I'm still not sure how to fix this, so this might or might not be fixed in the future.

With the advent of encoding/json v2, and the fact that more performant custom JSON package exist, I'm not very keen to spend time working on this package.

@ziemekobel-ef
Copy link
Author

Yeah, I can totally understand it. TBH I would use goccy/go-json if they had FormatNilMapAsNull implemented. Encoding/json v2 does have it implemented, but for now for our payloads it is 30 % slower than standard encoding/json.

@takanuva15
Copy link

takanuva15 commented Dec 17, 2024

@wI2L Hey I was looking at this library for its ability to customize the encoding of time.Time without needing to define a custom time.Time wrapper. You mentioned above that goccy/go-json exists as a "more performant custom JSON package", but when I look at its documentation, I don't see any way to customize the marshalling of time.Time without declaring the dummy wrapper struct that everyone says is the standard approach.

Can you clarify whether goccy/go-json actually can do the custom time encoding functionality that this package can do? (Right now, that doesn't look to be the case)

@wI2L
Copy link
Owner

wI2L commented Dec 18, 2024

@takanuva15 Not to my knowledge, but that's because goccy/go-json implement exactly the API the same way as the official encoding/json package, whereas this package adds some custom features,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants