From d287a39cb902713ab0e5dff2f300c4e161ceb3d7 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 10 Feb 2023 18:31:41 -0700 Subject: decode: Replace .panicType() with .newTypeError() --- decode.go | 74 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'decode.go') diff --git a/decode.go b/decode.go index b206a88..a79f7cd 100644 --- a/decode.go +++ b/decode.go @@ -254,8 +254,8 @@ func (dec *Decoder) Decode(ptr any) (err error) { type decodeError DecodeError -func (dec *Decoder) panicType(jTyp string, gTyp reflect.Type, err error) { - panic(decodeError{ +func (dec *Decoder) newTypeError(jTyp string, gTyp reflect.Type, err error) *DecodeError { + return &DecodeError{ Field: dec.structStackStr(), FieldParent: dec.structStackParent(), FieldName: dec.structStackName(), @@ -265,7 +265,7 @@ func (dec *Decoder) panicType(jTyp string, gTyp reflect.Type, err error) { Err: err, Offset: dec.posStack[len(dec.posStack)-1], }, - }) + } } func (dec *Decoder) readRune() (rune, jsonparse.RuneType) { @@ -305,7 +305,8 @@ func (dec *Decoder) expectRune(ec rune, et jsonparse.RuneType) { func (dec *Decoder) expectRuneType(ec rune, et jsonparse.RuneType, gt reflect.Type) { ac, at := dec.readRune() if ac != ec || at != et { - dec.panicType(at.JSONType(), gt, nil) + err := dec.newTypeError(at.JSONType(), gt, nil) + panic(decodeError(*err)) } } @@ -399,17 +400,17 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { var buf bytes.Buffer dec.scan(&buf) if err := val.Addr().Interface().(*RawMessage).UnmarshalJSON(buf.Bytes()); err != nil { - dec.panicType(t.JSONType(), reflect.PointerTo(typ), err) + return dec.newTypeError(t.JSONType(), reflect.PointerTo(typ), err) } case val.CanAddr() && reflect.PointerTo(typ).Implements(decodableType): t := dec.peekRuneType() obj := val.Addr().Interface().(Decodable) return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError { if err := obj.DecodeJSON(l); err != nil { - dec.panicType(t.JSONType(), reflect.PointerTo(typ), err) + return dec.newTypeError(t.JSONType(), reflect.PointerTo(typ), err) } if _, _, err := l.ReadRune(); err != io.EOF { - dec.panicType(t.JSONType(), reflect.PointerTo(typ), fmt.Errorf("did not consume entire %s", t.JSONType())) + return dec.newTypeError(t.JSONType(), reflect.PointerTo(typ), fmt.Errorf("did not consume entire %s", t.JSONType())) } return nil }) @@ -419,7 +420,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.scan(&buf) obj := val.Addr().Interface().(jsonUnmarshaler) if err := obj.UnmarshalJSON(buf.Bytes()); err != nil { - dec.panicType(t.JSONType(), reflect.PointerTo(typ), err) + return dec.newTypeError(t.JSONType(), reflect.PointerTo(typ), err) } case val.CanAddr() && reflect.PointerTo(typ).Implements(textUnmarshalerType): if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { @@ -430,7 +431,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.decodeString(reflect.PointerTo(typ), &buf) obj := val.Addr().Interface().(encoding.TextUnmarshaler) if err := obj.UnmarshalText(buf.Bytes()); err != nil { - dec.panicType("string", reflect.PointerTo(typ), err) + return dec.newTypeError("string", reflect.PointerTo(typ), err) } default: switch kind := typ.Kind(); kind { @@ -449,7 +450,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.scanNumber(typ, &buf) n, err := strconv.ParseInt(buf.String(), 10, kind2bits[kind]) if err != nil { - dec.panicType("number "+buf.String(), typ, err) + return dec.newTypeError("number "+buf.String(), typ, err) } val.SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: @@ -461,7 +462,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.scanNumber(typ, &buf) n, err := strconv.ParseUint(buf.String(), 10, kind2bits[kind]) if err != nil { - dec.panicType("number "+buf.String(), typ, err) + return dec.newTypeError("number "+buf.String(), typ, err) } val.SetUint(n) case reflect.Float32, reflect.Float64: @@ -473,7 +474,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.scanNumber(typ, &buf) n, err := strconv.ParseFloat(buf.String(), kind2bits[kind]) if err != nil { - dec.panicType("number "+buf.String(), typ, err) + return dec.newTypeError("number "+buf.String(), typ, err) } val.SetFloat(n) case reflect.String: @@ -486,7 +487,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { t := dec.peekRuneType() dec.scan(&buf) if !t.IsNumber() { - dec.panicType(t.JSONType(), typ, + return dec.newTypeError(t.JSONType(), typ, fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", buf.String())) } @@ -497,7 +498,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { } case reflect.Interface: if typ.NumMethod() > 0 { - dec.panicType(dec.peekRuneType().JSONType(), typ, ErrDecodeNonEmptyInterface) + return dec.newTypeError(dec.peekRuneType().JSONType(), typ, ErrDecodeNonEmptyInterface) } // If the interface stores a pointer, try to use the type information of the pointer. if !val.IsNil() && val.Elem().Kind() == reflect.Pointer { @@ -572,7 +573,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { } if !ok { if dec.disallowUnknownFields { - dec.panicType("", typ, fmt.Errorf("json: unknown field %q", name)) + return dec.newTypeError("", typ, fmt.Errorf("json: unknown field %q", name)) } dec.scan(fastio.Discard) return nil @@ -582,7 +583,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { for _, idx := range field.Path { if fVal.Kind() == reflect.Pointer { if fVal.IsNil() && !fVal.CanSet() { // https://golang.org/issue/21357 - dec.panicType("", fVal.Type().Elem(), + return dec.newTypeError("", fVal.Type().Elem(), fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", fVal.Type().Elem())) } @@ -613,13 +614,13 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { dec.decodeString(nil, &buf) if err := NewDecoder(bytes.NewReader(buf.Bytes())).Decode(fVal.Addr().Interface()); err != nil { if str := buf.String(); str != "null" { - dec.panicType("", fVal.Type(), + return dec.newTypeError("", fVal.Type(), fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", str, fVal.Type())) } } default: - dec.panicType(t.JSONType(), fVal.Type(), + return dec.newTypeError(t.JSONType(), fVal.Type(), fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", fVal.Type())) } @@ -650,7 +651,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { case reflect.PointerTo(nameValTyp).Implements(textUnmarshalerType): obj := nameValPtr.Interface().(encoding.TextUnmarshaler) if err := obj.UnmarshalText(nameBuf.Bytes()); err != nil { - dec.panicType("string", reflect.PointerTo(nameValTyp), err) + return dec.newTypeError("string", reflect.PointerTo(nameValTyp), err) } default: switch nameValTyp.Kind() { @@ -659,17 +660,17 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: n, err := strconv.ParseInt(nameBuf.String(), 10, kind2bits[nameValTyp.Kind()]) if err != nil { - dec.panicType("number "+nameBuf.String(), nameValTyp, err) + return dec.newTypeError("number "+nameBuf.String(), nameValTyp, err) } nameValPtr.Elem().SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: n, err := strconv.ParseUint(nameBuf.String(), 10, kind2bits[nameValTyp.Kind()]) if err != nil { - dec.panicType("number "+nameBuf.String(), nameValTyp, err) + return dec.newTypeError("number "+nameBuf.String(), nameValTyp, err) } nameValPtr.Elem().SetUint(n) default: - dec.panicType("object", typ, &DecodeArgumentError{Type: nameValTyp}) + return dec.newTypeError("object", typ, &DecodeArgumentError{Type: nameValTyp}) } } return nil @@ -688,7 +689,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { return nil }) default: - dec.panicType(t.JSONType(), typ, nil) + return dec.newTypeError(t.JSONType(), typ, nil) } case reflect.Slice: switch { @@ -717,7 +718,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { } } default: - dec.panicType(t.JSONType(), typ, nil) + return dec.newTypeError(t.JSONType(), typ, nil) } default: switch t := dec.peekRuneType(); t { @@ -746,7 +747,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { return nil }) default: - dec.panicType(t.JSONType(), typ, nil) + return dec.newTypeError(t.JSONType(), typ, nil) } } case reflect.Array: @@ -790,7 +791,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { return dec.decode(val.Elem(), false) } default: - dec.panicType("", typ, fmt.Errorf("unsupported type (kind=%v)", typ.Kind())) + return dec.newTypeError("", typ, fmt.Errorf("unsupported type (kind=%v)", typ.Kind())) } } return nil @@ -810,7 +811,8 @@ func (dec *Decoder) scan(out fastio.RuneWriter) { func (dec *Decoder) scanNumber(gTyp reflect.Type, out fastio.RuneWriter) { if t := dec.peekRuneType(); !t.IsNumber() { - dec.panicType(t.JSONType(), gTyp, nil) + err := dec.newTypeError(t.JSONType(), gTyp, nil) + panic(decodeError(*err)) } dec.scan(out) } @@ -876,7 +878,7 @@ func (dec *Decoder) decodeAny() (any, *DecodeError) { } f64, err := num.Float64() if err != nil { - dec.panicType("number "+buf.String(), float64Type, err) + return nil, dec.newTypeError("number "+buf.String(), float64Type, err) } return f64, nil case 't', 'f': @@ -923,11 +925,11 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError { if err := decodeKey(l); err != nil { // TODO: Find a better Go type to use than `nil`. - dec.panicType("string", nil, err) + return dec.newTypeError("string", nil, err) } if _, _, err := l.ReadRune(); err != io.EOF { // TODO: Find a better Go type to use than `nil`. - dec.panicType("string", nil, fmt.Errorf("did not consume entire string")) + return dec.newTypeError("string", nil, fmt.Errorf("did not consume entire string")) } return nil }) @@ -939,11 +941,11 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError { if err := decodeVal(l); err != nil { // TODO: Find a better Go type to use than `nil`. - dec.panicType(t.JSONType(), nil, err) + return dec.newTypeError(t.JSONType(), nil, err) } if _, _, err := l.ReadRune(); err != io.EOF { // TODO: Find a better Go type to use than `nil`. - dec.panicType(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType())) + return dec.newTypeError(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType())) } return nil }) @@ -1018,11 +1020,11 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError { if err := decodeMember(l); err != nil { // TODO: Find a better Go type to use than `nil`. - dec.panicType(t.JSONType(), nil, err) + return dec.newTypeError(t.JSONType(), nil, err) } if _, _, err := l.ReadRune(); err != io.EOF { // TODO: Find a better Go type to use than `nil`. - dec.panicType(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType())) + return dec.newTypeError(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType())) } return nil }) @@ -1159,8 +1161,8 @@ func (dec *Decoder) decodeBool(gTyp reflect.Type) bool { dec.expectRune('e', jsonparse.RuneTypeFalseE) return false default: - dec.panicType(t.JSONType(), gTyp, nil) - panic("not reached") + err := dec.newTypeError(t.JSONType(), gTyp, nil) + panic(decodeError(*err)) } } -- cgit v1.2.3-2-g168b