state: move nil check down to stackitem JSON processing

We want to return real errors, not some generic thing for any kind of thing
happening.
This commit is contained in:
Roman Khimov 2021-07-07 00:38:19 +03:00
parent 5a9efcc654
commit e62a766058
3 changed files with 12 additions and 9 deletions

View file

@ -194,10 +194,6 @@ func (e Execution) MarshalJSON() ([]byte, error) {
var errRecursive = []byte(`"error: recursive reference"`) var errRecursive = []byte(`"error: recursive reference"`)
arr := make([]json.RawMessage, len(e.Stack)) arr := make([]json.RawMessage, len(e.Stack))
for i := range arr { for i := range arr {
if e.Stack[i] == nil {
arr[i] = errRecursive
continue
}
data, err := stackitem.ToJSONWithTypes(e.Stack[i]) data, err := stackitem.ToJSONWithTypes(e.Stack[i])
if err != nil { if err != nil {
data = errRecursive data = errRecursive

View file

@ -184,7 +184,13 @@ func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) {
bs1, err := json.Marshal(actual) bs1, err := json.Marshal(actual)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, bs, bs1) require.NotEqual(t, bs, bs1) // recursive ref error vs. unserializable nil
actual2 := new(AppExecResult)
require.NoError(t, json.Unmarshal(bs, actual2))
bs2, err := json.Marshal(actual2)
require.NoError(t, err)
require.Equal(t, bs1, bs2) // unserializable nil in both cases
}) })
t.Run("UnmarshalJSON error", func(t *testing.T) { t.Run("UnmarshalJSON error", func(t *testing.T) {

View file

@ -232,10 +232,6 @@ func toJSONWithTypes(item Item, seen map[Item]bool) (interface{}, error) {
if len(seen) > MaxJSONDepth { if len(seen) > MaxJSONDepth {
return "", ErrTooDeep return "", ErrTooDeep
} }
typ := item.Type()
result := map[string]interface{}{
"type": typ.String(),
}
var value interface{} var value interface{}
switch it := item.(type) { switch it := item.(type) {
case *Array, *Struct: case *Array, *Struct:
@ -281,6 +277,11 @@ func toJSONWithTypes(item Item, seen map[Item]bool) (interface{}, error) {
delete(seen, item) delete(seen, item)
case *Pointer: case *Pointer:
value = it.pos value = it.pos
case nil:
return "", fmt.Errorf("%w: nil", ErrUnserializable)
}
result := map[string]interface{}{
"type": item.Type().String(),
} }
if value != nil { if value != nil {
result["value"] = value result["value"] = value