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: use the Error method to marshal an error value? #5161

orofarne opened this issue Mar 30, 2013 · 8 comments

encoding/json: use the Error method to marshal an error value? #5161

orofarne opened this issue Mar 30, 2013 · 8 comments


Copy link

orofarne commented Mar 30, 2013

What steps will reproduce the problem?

What is the expected output?
Something like this:

What do you see instead?

Which compiler are you using (5g, 6g, 8g, gccgo)?

Which operating system are you using?
Linux (Ubuntu 12.04, 3.2.0-38-generic)

Which version are you using?  (run 'go version')
go version go1.0.3
go version devel +5260abd6df41 Sat Mar 30 19:05:00 2013 +0800 linux/amd64

Please provide any additional information below.
I think it's not intuitive behaviour. fmt prints errors without problems, why json not?
Copy link

remyoudompheng commented Mar 30, 2013

Comment 1:

See also issue #3353.

Copy link

gopherbot commented Jul 27, 2013

Comment 2 by pongad:

I believe this is the expected behavior of json.Marshal(interfaceValue). According to
the documentation, if the argument is an interface value, it is encodes the value of
that interface.
The implementation of fmt.Errorf uses errors.errorString type. The type is a struct with
one unexported member 's' which holds the error. Since the member is unexported,
json.Marshal does not care to encode it.
A possible workaround is to create a new error type that both satisfies "error" and
"json.Marshaler" like

Copy link

adg commented Jul 29, 2013

Comment 3:

Not sure what the right move is, here. Or even if we can fix it at all. There may be
code that relies on the JSON marhsaller *not* using the Error method to marshal a value.

Labels changed: added priority-later, removed priority-triage.

Status changed to Thinking.

Copy link

rsc commented Nov 27, 2013

Comment 4:

Labels changed: added go1.3maybe.

Copy link

rsc commented Dec 4, 2013

Comment 5:

Labels changed: added release-none, removed go1.3maybe.

Copy link

rsc commented Dec 4, 2013

Comment 6:

Labels changed: added repo-main.

Copy link

dimandzhi commented Mar 16, 2021

Hi! I hate to be the one who breaks the almost-a-decade silence, but after several years of using golang I've stumbled uppon a piece of code that uses JSON marshaling of an error interface value. Guess, it is a rare scenario. 😄 Well, result of {"err": {}} wasn't very informative. I realise, that errors interface puprpose is to provide a method to give stringified message of error (with according format for logging even), which doesn't mean it's meant to be marshaled into JSON the same way.
I think adding a configuration option (not default) to json.Encoder to enable using Error() method to encode value if there is no MarshalJSON() method will help everyone to achieve desired behavior without the need of creating a special type for that.

Copy link

micklove commented Aug 31, 2021

FYI - Had the same issue, expected the error string to be in the json output...
after various searches, ended up with this...
(would love to know if there's a simpler approach)

My original struct

type Result struct {
    Score   int
    Error   error

Implmented MarshalJSON on the Result struct

// MarshalJSON -
// create anonymous struct to generate a different representation of the Result, containing the Error() string, 
// as the error interface's string won't be marshaled by default
func (r Result) MarshalJSON() ([]byte, error) {
    var errorMsg string
    if r.Error != nil {
        errorMsg = r.Error.Error()
    anon := struct {
        Score   int    `json:"score"`
        Error   string `json:"error"`
        Score:   r.Score,
        Error:   errorMsg,
    return json.Marshal(anon)

JSON output

   "score": 25,
    "error": "did not qualify"

adrienthebo added a commit to gitpod-io/gitbot that referenced this issue Nov 3, 2022
per golang/go#5161 serializing an `error` object to json emits an empty object; this caused deployed-labeler to emit an empty object when erroring. This commit converts all errors to strings before returning to the user to provide more context.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

7 participants