• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / go-tarantool / 13930913017

18 Mar 2025 06:33PM UTC coverage: 75.939% (+0.08%) from 75.863%
13930913017

Pull #435

github

maksim.konovalov
pool: Pooler interface supports GetInfo method in TopologyEditor
Pull Request #435: pool: Pooler interface supports GetInfo method in TopologyEditor

2992 of 3940 relevant lines covered (75.94%)

9863.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.51
/box_error.go
1
package tarantool
2

3
import (
4
        "bytes"
5
        "fmt"
6

7
        "github.com/vmihailenco/msgpack/v5"
8
)
9

10
const errorExtID = 3
11

12
const (
13
        keyErrorStack   = 0x00
14
        keyErrorType    = 0x00
15
        keyErrorFile    = 0x01
16
        keyErrorLine    = 0x02
17
        keyErrorMessage = 0x03
18
        keyErrorErrno   = 0x04
19
        keyErrorErrcode = 0x05
20
        keyErrorFields  = 0x06
21
)
22

23
// BoxError is a type representing Tarantool `box.error` object: a single
24
// MP_ERROR_STACK object with a link to the previous stack error.
25
// See https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_error/error/
26
//
27
// Since 1.10.0
28
type BoxError struct {
29
        // Type is error type that implies its source (for example, "ClientError").
30
        Type string
31
        // File is a source code file where the error was caught.
32
        File string
33
        // Line is a number of line in the source code file where the error was caught.
34
        Line uint64
35
        // Msg is the text of reason.
36
        Msg string
37
        // Errno is the ordinal number of the error.
38
        Errno uint64
39
        // Code is the number of the error as defined in `errcode.h`.
40
        Code uint64
41
        // Fields are additional fields depending on error type. For example, if
42
        // type is "AccessDeniedError", then it will include "object_type",
43
        // "object_name", "access_type".
44
        Fields map[string]interface{}
45
        // Prev is the previous error in stack.
46
        Prev *BoxError
47
}
48

49
// Error converts a BoxError to a string.
50
func (e *BoxError) Error() string {
8✔
51
        s := fmt.Sprintf("%s (%s, code 0x%x), see %s line %d",
8✔
52
                e.Msg, e.Type, e.Code, e.File, e.Line)
8✔
53

8✔
54
        if e.Prev != nil {
9✔
55
                return fmt.Sprintf("%s: %s", s, e.Prev)
1✔
56
        }
1✔
57

58
        return s
7✔
59
}
60

61
// Depth computes the count of errors in stack, including the current one.
62
func (e *BoxError) Depth() int {
33✔
63
        depth := int(0)
33✔
64

33✔
65
        cur := e
33✔
66
        for cur != nil {
77✔
67
                cur = cur.Prev
44✔
68
                depth++
44✔
69
        }
44✔
70

71
        return depth
33✔
72
}
73

74
func decodeBoxError(d *msgpack.Decoder) (*BoxError, error) {
55✔
75
        var l, larr, l1, l2 int
55✔
76
        var errorStack []BoxError
55✔
77
        var err error
55✔
78

55✔
79
        if l, err = d.DecodeMapLen(); err != nil {
56✔
80
                return nil, err
1✔
81
        }
1✔
82

83
        for ; l > 0; l-- {
109✔
84
                var cd int
55✔
85
                if cd, err = d.DecodeInt(); err != nil {
56✔
86
                        return nil, err
1✔
87
                }
1✔
88
                switch cd {
54✔
89
                case keyErrorStack:
52✔
90
                        if larr, err = d.DecodeArrayLen(); err != nil {
53✔
91
                                return nil, err
1✔
92
                        }
1✔
93

94
                        errorStack = make([]BoxError, larr)
51✔
95

51✔
96
                        for i := 0; i < larr; i++ {
110✔
97
                                if l1, err = d.DecodeMapLen(); err != nil {
60✔
98
                                        return nil, err
1✔
99
                                }
1✔
100

101
                                for ; l1 > 0; l1-- {
370✔
102
                                        var cd1 int
312✔
103
                                        if cd1, err = d.DecodeInt(); err != nil {
313✔
104
                                                return nil, err
1✔
105
                                        }
1✔
106
                                        switch cd1 {
311✔
107
                                        case keyErrorType:
46✔
108
                                                if errorStack[i].Type, err = d.DecodeString(); err != nil {
47✔
109
                                                        return nil, err
1✔
110
                                                }
1✔
111
                                        case keyErrorFile:
46✔
112
                                                if errorStack[i].File, err = d.DecodeString(); err != nil {
47✔
113
                                                        return nil, err
1✔
114
                                                }
1✔
115
                                        case keyErrorLine:
47✔
116
                                                if errorStack[i].Line, err = d.DecodeUint64(); err != nil {
48✔
117
                                                        return nil, err
1✔
118
                                                }
1✔
119
                                        case keyErrorMessage:
46✔
120
                                                if errorStack[i].Msg, err = d.DecodeString(); err != nil {
47✔
121
                                                        return nil, err
1✔
122
                                                }
1✔
123
                                        case keyErrorErrno:
46✔
124
                                                if errorStack[i].Errno, err = d.DecodeUint64(); err != nil {
47✔
125
                                                        return nil, err
1✔
126
                                                }
1✔
127
                                        case keyErrorErrcode:
46✔
128
                                                if errorStack[i].Code, err = d.DecodeUint64(); err != nil {
47✔
129
                                                        return nil, err
1✔
130
                                                }
1✔
131
                                        case keyErrorFields:
32✔
132
                                                var mapk string
32✔
133
                                                var mapv interface{}
32✔
134

32✔
135
                                                errorStack[i].Fields = make(map[string]interface{})
32✔
136

32✔
137
                                                if l2, err = d.DecodeMapLen(); err != nil {
33✔
138
                                                        return nil, err
1✔
139
                                                }
1✔
140
                                                for ; l2 > 0; l2-- {
100✔
141
                                                        if mapk, err = d.DecodeString(); err != nil {
70✔
142
                                                                return nil, err
1✔
143
                                                        }
1✔
144
                                                        if mapv, err = d.DecodeInterface(); err != nil {
69✔
145
                                                                return nil, err
1✔
146
                                                        }
1✔
147
                                                        errorStack[i].Fields[mapk] = mapv
67✔
148
                                                }
149
                                        default:
2✔
150
                                                if err = d.Skip(); err != nil {
3✔
151
                                                        return nil, err
1✔
152
                                                }
1✔
153
                                        }
154
                                }
155

156
                                if i > 0 {
56✔
157
                                        errorStack[i-1].Prev = &errorStack[i]
9✔
158
                                }
9✔
159
                        }
160
                default:
2✔
161
                        if err = d.Skip(); err != nil {
3✔
162
                                return nil, err
1✔
163
                        }
1✔
164
                }
165
        }
166

167
        if len(errorStack) == 0 {
40✔
168
                return nil, fmt.Errorf("msgpack: unexpected empty BoxError stack on decode")
1✔
169
        }
1✔
170

171
        return &errorStack[0], nil
38✔
172
}
173

174
func encodeBoxError(enc *msgpack.Encoder, boxError *BoxError) error {
16✔
175
        if boxError == nil {
17✔
176
                return fmt.Errorf("msgpack: unexpected nil BoxError on encode")
1✔
177
        }
1✔
178

179
        if err := enc.EncodeMapLen(1); err != nil {
15✔
180
                return err
×
181
        }
×
182
        if err := enc.EncodeUint(keyErrorStack); err != nil {
15✔
183
                return err
×
184
        }
×
185

186
        var stackDepth = boxError.Depth()
15✔
187
        if err := enc.EncodeArrayLen(stackDepth); err != nil {
15✔
188
                return err
×
189
        }
×
190

191
        for ; stackDepth > 0; stackDepth-- {
35✔
192
                fieldsLen := len(boxError.Fields)
20✔
193

20✔
194
                if fieldsLen > 0 {
25✔
195
                        if err := enc.EncodeMapLen(7); err != nil {
5✔
196
                                return err
×
197
                        }
×
198
                } else {
15✔
199
                        if err := enc.EncodeMapLen(6); err != nil {
15✔
200
                                return err
×
201
                        }
×
202
                }
203

204
                if err := enc.EncodeUint(keyErrorType); err != nil {
20✔
205
                        return err
×
206
                }
×
207
                if err := enc.EncodeString(boxError.Type); err != nil {
20✔
208
                        return err
×
209
                }
×
210

211
                if err := enc.EncodeUint(keyErrorFile); err != nil {
20✔
212
                        return err
×
213
                }
×
214
                if err := enc.EncodeString(boxError.File); err != nil {
20✔
215
                        return err
×
216
                }
×
217

218
                if err := enc.EncodeUint(keyErrorLine); err != nil {
20✔
219
                        return err
×
220
                }
×
221
                if err := enc.EncodeUint64(boxError.Line); err != nil {
20✔
222
                        return err
×
223
                }
×
224

225
                if err := enc.EncodeUint(keyErrorMessage); err != nil {
20✔
226
                        return err
×
227
                }
×
228
                if err := enc.EncodeString(boxError.Msg); err != nil {
20✔
229
                        return err
×
230
                }
×
231

232
                if err := enc.EncodeUint(keyErrorErrno); err != nil {
20✔
233
                        return err
×
234
                }
×
235
                if err := enc.EncodeUint64(boxError.Errno); err != nil {
20✔
236
                        return err
×
237
                }
×
238

239
                if err := enc.EncodeUint(keyErrorErrcode); err != nil {
20✔
240
                        return err
×
241
                }
×
242
                if err := enc.EncodeUint64(boxError.Code); err != nil {
20✔
243
                        return err
×
244
                }
×
245

246
                if fieldsLen > 0 {
25✔
247
                        if err := enc.EncodeUint(keyErrorFields); err != nil {
5✔
248
                                return err
×
249
                        }
×
250

251
                        if err := enc.EncodeMapLen(fieldsLen); err != nil {
5✔
252
                                return err
×
253
                        }
×
254

255
                        for k, v := range boxError.Fields {
20✔
256
                                if err := enc.EncodeString(k); err != nil {
15✔
257
                                        return err
×
258
                                }
×
259
                                if err := enc.Encode(v); err != nil {
15✔
260
                                        return err
×
261
                                }
×
262
                        }
263
                }
264

265
                if stackDepth > 1 {
25✔
266
                        boxError = boxError.Prev
5✔
267
                }
5✔
268
        }
269

270
        return nil
15✔
271
}
272

273
// UnmarshalMsgpack deserializes a BoxError value from a MessagePack
274
// representation.
275
func (e *BoxError) UnmarshalMsgpack(b []byte) error {
41✔
276
        if e == nil {
42✔
277
                panic("cannot unmarshal to a nil pointer")
1✔
278
        }
279

280
        buf := bytes.NewBuffer(b)
40✔
281
        dec := msgpack.NewDecoder(buf)
40✔
282

40✔
283
        if val, err := decodeBoxError(dec); err != nil {
57✔
284
                return err
17✔
285
        } else {
40✔
286
                *e = *val
23✔
287
                return nil
23✔
288
        }
23✔
289
}
290

291
// MarshalMsgpack serializes the BoxError into a MessagePack representation.
292
func (e *BoxError) MarshalMsgpack() ([]byte, error) {
16✔
293
        var buf bytes.Buffer
16✔
294

16✔
295
        enc := msgpack.NewEncoder(&buf)
16✔
296
        if err := encodeBoxError(enc, e); err != nil {
17✔
297
                return nil, err
1✔
298
        }
1✔
299

300
        return buf.Bytes(), nil
15✔
301
}
302

303
func init() {
1✔
304
        msgpack.RegisterExt(errorExtID, (*BoxError)(nil))
1✔
305
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc