1
2
3
4
5
6
7 package json
8
9 import (
10 "fmt"
11 "reflect"
12 "strconv"
13 "strings"
14
15 "encoding/json/internal"
16 "encoding/json/jsontext"
17 jsonv2 "encoding/json/v2"
18 )
19
20
21 func init() {
22 internal.TransformMarshalError = transformMarshalError
23 internal.TransformUnmarshalError = transformUnmarshalError
24 internal.NewMarshalerError = func(val any, err error, funcName string) error {
25 return &MarshalerError{reflect.TypeOf(val), err, funcName}
26 }
27
28 internal.NewRawNumber = func() any { return new(Number) }
29 internal.RawNumberOf = func(b []byte) any { return Number(b) }
30 }
31
32 func transformMarshalError(root any, err error) error {
33
34
35
36
37
38
39 if err, ok := err.(*jsonv2.SemanticError); err != nil {
40 if err.Err == nil {
41
42
43 return &UnsupportedTypeError{Type: err.GoType}
44 } else {
45
46
47
48
49 errStr := err.Err.Error()
50 if err.Err == internal.ErrCycle && err.GoType != nil {
51 errStr += " via " + err.GoType.String()
52 }
53 errStr = strings.TrimPrefix(errStr, "unsupported value: ")
54 return &UnsupportedValueError{Str: errStr}
55 }
56 } else if ok {
57 return (*UnsupportedValueError)(nil)
58 }
59 if err, _ := err.(*MarshalerError); err != nil {
60 err.Err = transformSyntacticError(err.Err)
61 return err
62 }
63 return transformSyntacticError(err)
64 }
65
66 func transformUnmarshalError(root any, err error) error {
67
68
69 if err, ok := err.(*jsonv2.SemanticError); err != nil {
70 if err.Err == internal.ErrNonNilReference {
71 return &InvalidUnmarshalError{err.GoType}
72 }
73 if err.Err == jsonv2.ErrUnknownName {
74 return fmt.Errorf("json: unknown field %q", err.JSONPointer.LastToken())
75 }
76 if err.Err == internal.ErrNilInterface {
77 err.Err = nil
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 var value string
101 switch err.JSONKind {
102 case 'n', '"', '0':
103 value = err.JSONKind.String()
104 case 'f', 't':
105 value = "bool"
106 case '[', ']':
107 value = "array"
108 case '{', '}':
109 value = "object"
110 }
111 if len(err.JSONValue) > 0 {
112 isStrconvError := err.Err == strconv.ErrRange || err.Err == strconv.ErrSyntax
113 isNumericKind := func(t reflect.Type) bool {
114 if t == nil {
115 return false
116 }
117 switch t.Kind() {
118 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
119 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
120 reflect.Float32, reflect.Float64:
121 return true
122 }
123 return false
124 }
125 if isStrconvError && isNumericKind(err.GoType) {
126 value = "number"
127 if err.JSONKind == '"' {
128 err.JSONValue, _ = jsontext.AppendUnquote(nil, err.JSONValue)
129 }
130 err.Err = nil
131 }
132 value += " " + string(err.JSONValue)
133 }
134 var rootName string
135 if t := reflect.TypeOf(root); t != nil && err.JSONPointer != "" {
136 if t.Kind() == reflect.Pointer {
137 t = t.Elem()
138 }
139 rootName = t.Name()
140 }
141 fieldPath := string(err.JSONPointer)
142 fieldPath = strings.TrimPrefix(fieldPath, "/")
143 fieldPath = strings.ReplaceAll(fieldPath, "/", ".")
144 return &UnmarshalTypeError{
145 Value: value,
146 Type: err.GoType,
147 Offset: err.ByteOffset,
148 Struct: rootName,
149 Field: fieldPath,
150 Err: transformSyntacticError(err.Err),
151 }
152 } else if ok {
153 return (*UnmarshalTypeError)(nil)
154 }
155 return transformSyntacticError(err)
156 }
157
View as plain text