Gqlgen: json: error calling MarshalJSON for type json.RawMessage:

Created on 18 Oct 2018  路  2Comments  路  Source: 99designs/gqlgen

I've run into this error trying to define a custom scalar for the time.Time type, slightly modifying the example from the docs.

Error Message
json: error calling MarshalJSON for type json.RawMessage: invalid character '-' after object key:value pair

Expected Behaviour

custom Scalar should return a stringified timestamp

Actual Behavior

panic during unmarshall

Minimal graphql.schema and models to reproduce

Scalars

func MarshalTimestamp(t time.Time) graphql.Marshaler {
    return graphql.WriterFunc(func(w io.Writer) {
        io.WriteString(w, t.Format(time.RFC3339Nano))
    })
}

Schema

type Test {
    createdAt: Timestamp!
}
scalar Timestamp

Model

type Test struct {
    CreatedAt time.Time `json:"createdAt"`
}

example of a timestamp received by the marshaller:
2018-10-18 04:14:08.887 +0000 UTC

panic messages

json: error calling MarshalJSON for type json.RawMessage: invalid character '-' after object key:value pair

goroutine 21 [running]:
runtime/debug.Stack(0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.2/libexec/src/runtime/debug/stack.go:24 +0xa7
runtime/debug.PrintStack()
    /usr/local/Cellar/go/1.10.2/libexec/src/runtime/debug/stack.go:16 +0x22
github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/graphql.DefaultRecover(0x14ae8e0, 0xc4202925a0, 0x13d8920, 0xc4202c0aa0, 0x199, 0xc420160100)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/graphql/recovery.go:16 +0xa7
github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/handler.GraphQL.func1.1(0xc42016d880, 0x14ae8e0, 0xc4202925a0, 0x14ae4e0, 0xc42017e1c0)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/handler/graphql.go:234 +0x73
panic(0x13d8920, 0xc4202c0aa0)
    /usr/local/Cellar/go/1.10.2/libexec/src/runtime/panic.go:502 +0x229
github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/handler.GraphQL.func1(0x14ae4e0, 0xc42017e1c0, 0xc42015c700)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/vendor/github.com/99designs/gqlgen/handler/graphql.go:251 +0xf6b
github.com/launchpadcentral/glidr-gateway/adapters.WithClaims.func1.1(0x14ae4e0, 0xc42017e1c0, 0xc42015c600)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/adapters/adapters.go:78 +0x4ff
github.com/launchpadcentral/glidr-gateway/adapters.WithLogger.func1.1(0x14ae4e0, 0xc42017e1c0, 0xc42015c500)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/adapters/adapters.go:46 +0x5b
github.com/launchpadcentral/glidr-gateway/adapters.Adapt.func1(0x14ae4e0, 0xc42017e1c0, 0xc42015c500)
    /Users/qhenkart/workspace/launchpad/glidr-dev/go/src/github.com/launchpadcentral/glidr-gateway/adapters/adapters.go:37 +0x43
net/http.HandlerFunc.ServeHTTP(0xc4201c57b0, 0x14ae4e0, 0xc42017e1c0, 0xc42015c500)
    /usr/local/Cellar/go/1.10.2/libexec/src/net/http/server.go:1947 +0x44
net/http.(*ServeMux).ServeHTTP(0x16b8ea0, 0x14ae4e0, 0xc42017e1c0, 0xc42015c500)
    /usr/local/Cellar/go/1.10.2/libexec/src/net/http/server.go:2337 +0x130
net/http.serverHandler.ServeHTTP(0xc4200ade10, 0x14ae4e0, 0xc42017e1c0, 0xc42015c500)
    /usr/local/Cellar/go/1.10.2/libexec/src/net/http/server.go:2694 +0xbc
net/http.(*conn).serve(0xc4202745a0, 0x14ae820, 0xc42027ec80)
    /usr/local/Cellar/go/1.10.2/libexec/src/net/http/server.go:1830 +0x651
created by net/http.(*Server).Serve
    /usr/local/Cellar/go/1.10.2/libexec/src/net/http/server.go:2795 +0x27b

Most helpful comment

the thing returned by the marshaller needs to be valid json, you're currently writing an unquoted date out.

eg:

{
    "foo": 2018-10-10 00:00:00
}

this is not valid json!

you probably want

func MarshalTimestamp(t time.Time) graphql.Marshaler {
    return graphql.WriterFunc(func(w io.Writer) {
        io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano)))
    })
}

to generate

{
    "foo": "2018-10-10 00:00:00"
}

All 2 comments

the thing returned by the marshaller needs to be valid json, you're currently writing an unquoted date out.

eg:

{
    "foo": 2018-10-10 00:00:00
}

this is not valid json!

you probably want

func MarshalTimestamp(t time.Time) graphql.Marshaler {
    return graphql.WriterFunc(func(w io.Writer) {
        io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano)))
    })
}

to generate

{
    "foo": "2018-10-10 00:00:00"
}

@vektah I understand now, thank you. I had a feeling it was something I was doing wrong

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sumanthakannantha picture sumanthakannantha  路  3Comments

RobertoOrtis picture RobertoOrtis  路  3Comments

itsbalamurali picture itsbalamurali  路  4Comments

huanghantao picture huanghantao  路  3Comments

jacksontj picture jacksontj  路  4Comments