How to handle json syntax error in a go test case?

1.9k views Asked by At

I'm testing a scenario where json.Unmarshall fails and returns

&json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}

the code is like this:

err = json.Unmarshal(input, &data)

if err != nil {
    return nil, err
}

test case is expecting this type of error:

{
...
errorType: &json.SyntaxError{},
...
}

the assertion is like this:

assert.Equal(t, tt.errorType, err)

which is failing because the error message is different:

expected: &json.SyntaxError{msg:"", Offset:0}
actual  : &json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}

How can I handle this? Perhaps making use of Error() ?

1

There are 1 answers

0
colm.anseo On BEST ANSWER

Firstly it's not possible to craft this sentinel error directly:

_ = &json.SyntaxError{msg: "unexpected end of JSON input", Offset: 0}  // msg field is not exported

the closest you can come is to check for the error type. To do this use errors.As

var tt *json.SyntaxError

if errors.As(err, &tt) {
    log.Printf("Syntax Error: %v", tt)
} else if err != nil {
    log.Fatalf("Fatal: %#v", err)
}

https://go.dev/play/p/mlqGN2ypwBs

You can check the Offset as that is public field. But to compare the non-public msg field, you'd need to use err.Error() - but this may be brittle as wording may change over time.


Note: errors.Is cannot be used here, as it only tests error equality: directly; or via error.Unwrap-ing.

Since the json.SyntaxError here is not wrapped - nor is it a sentinel error - it cannot be matched via errors.Is.