...
1
2
3
4
5 package gin
6
7 import (
8 "fmt"
9 "reflect"
10 "strings"
11
12 "github.com/gin-gonic/gin/internal/json"
13 )
14
15
16 type ErrorType uint64
17
18 const (
19
20 ErrorTypeBind ErrorType = 1 << 63
21
22 ErrorTypeRender ErrorType = 1 << 62
23
24 ErrorTypePrivate ErrorType = 1 << 0
25
26 ErrorTypePublic ErrorType = 1 << 1
27
28 ErrorTypeAny ErrorType = 1<<64 - 1
29
30 ErrorTypeNu = 2
31 )
32
33
34 type Error struct {
35 Err error
36 Type ErrorType
37 Meta any
38 }
39
40 type errorMsgs []*Error
41
42 var _ error = (*Error)(nil)
43
44
45 func (msg *Error) SetType(flags ErrorType) *Error {
46 msg.Type = flags
47 return msg
48 }
49
50
51 func (msg *Error) SetMeta(data any) *Error {
52 msg.Meta = data
53 return msg
54 }
55
56
57 func (msg *Error) JSON() any {
58 jsonData := H{}
59 if msg.Meta != nil {
60 value := reflect.ValueOf(msg.Meta)
61 switch value.Kind() {
62 case reflect.Struct:
63 return msg.Meta
64 case reflect.Map:
65 for _, key := range value.MapKeys() {
66 jsonData[key.String()] = value.MapIndex(key).Interface()
67 }
68 default:
69 jsonData["meta"] = msg.Meta
70 }
71 }
72 if _, ok := jsonData["error"]; !ok {
73 jsonData["error"] = msg.Error()
74 }
75 return jsonData
76 }
77
78
79 func (msg *Error) MarshalJSON() ([]byte, error) {
80 return json.Marshal(msg.JSON())
81 }
82
83
84 func (msg Error) Error() string {
85 return msg.Err.Error()
86 }
87
88
89 func (msg *Error) IsType(flags ErrorType) bool {
90 return (msg.Type & flags) > 0
91 }
92
93
94 func (msg *Error) Unwrap() error {
95 return msg.Err
96 }
97
98
99
100 func (a errorMsgs) ByType(typ ErrorType) errorMsgs {
101 if len(a) == 0 {
102 return nil
103 }
104 if typ == ErrorTypeAny {
105 return a
106 }
107 var result errorMsgs
108 for _, msg := range a {
109 if msg.IsType(typ) {
110 result = append(result, msg)
111 }
112 }
113 return result
114 }
115
116
117
118 func (a errorMsgs) Last() *Error {
119 if length := len(a); length > 0 {
120 return a[length-1]
121 }
122 return nil
123 }
124
125
126
127
128
129
130
131
132 func (a errorMsgs) Errors() []string {
133 if len(a) == 0 {
134 return nil
135 }
136 errorStrings := make([]string, len(a))
137 for i, err := range a {
138 errorStrings[i] = err.Error()
139 }
140 return errorStrings
141 }
142
143 func (a errorMsgs) JSON() any {
144 switch length := len(a); length {
145 case 0:
146 return nil
147 case 1:
148 return a.Last().JSON()
149 default:
150 jsonData := make([]any, length)
151 for i, err := range a {
152 jsonData[i] = err.JSON()
153 }
154 return jsonData
155 }
156 }
157
158
159 func (a errorMsgs) MarshalJSON() ([]byte, error) {
160 return json.Marshal(a.JSON())
161 }
162
163 func (a errorMsgs) String() string {
164 if len(a) == 0 {
165 return ""
166 }
167 var buffer strings.Builder
168 for i, msg := range a {
169 fmt.Fprintf(&buffer, "Error #%02d: %s\n", i+1, msg.Err)
170 if msg.Meta != nil {
171 fmt.Fprintf(&buffer, " Meta: %v\n", msg.Meta)
172 }
173 }
174 return buffer.String()
175 }
176
View as plain text