-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcerror.go
115 lines (112 loc) · 2.84 KB
/
cerror.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package cerror
import (
"context"
"encoding/json"
"log/slog"
"net/http"
"strconv"
"strings"
"github.com/chenjie199234/Corelib/util/common"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
)
func MakeCError(code int32, httpcode int32, msg string) *Error {
if code == 0 {
panic("error code can't be 0")
}
if httpcode < 400 {
panic("error's http code must >= 400")
}
if http.StatusText(int(httpcode)) == "" {
panic("error's http code unknown")
}
return &Error{
Code: code,
Httpcode: httpcode,
Msg: msg,
}
}
func (this *Error) Error() string {
return "code=" + strconv.FormatInt(int64(this.Code), 10) + ",msg=" + this.Msg
}
func (this *Error) Json() string {
d, _ := json.Marshal(this.Msg)
return "{\"code\":" + strconv.FormatInt(int64(this.Code), 10) + ",\"msg\":" + common.BTS(d) + "}"
}
func (this *Error) GRPCStatus() *status.Status {
return status.New(codes.Code(this.Httpcode), this.Error())
}
func (this *Error) SlogAttr() *slog.Attr {
return &slog.Attr{Key: "error", Value: slog.GroupValue(slog.Int64("code", int64(this.Code)), slog.String("msg", this.Msg))}
}
func (this *Error) SetHttpcode(httpcode int32) {
this.Httpcode = httpcode
}
func Equal(a, b error) bool {
aa := Convert(a)
bb := Convert(b)
if aa == nil && bb == nil {
return true
} else if (aa == nil && bb != nil) || (aa != nil && bb == nil) {
return false
}
return aa.Code == bb.Code && aa.Msg == bb.Msg
}
func Convert(e error) *Error {
if e == nil {
return nil
}
if e == context.DeadlineExceeded {
return ErrDeadlineExceeded
} else if e == context.Canceled {
return ErrCanceled
}
result, ok := e.(*Error)
if ok {
return result
}
return MakeCError(-1, 500, e.Error())
}
func Decode(estr string) *Error {
if estr == "" {
return nil
}
if estr == ErrDeadlineExceeded.Json() || estr == ErrDeadlineExceeded.Error() {
return ErrDeadlineExceeded
} else if estr == ErrCanceled.Json() || estr == ErrCanceled.Error() {
return ErrCanceled
}
if estr[0] == '{' && estr[len(estr)-1] == '}' {
//json format
tmp := &Error{}
//protojson can support "number string" or "number" for field:code
if e := (protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}).Unmarshal(common.STB(estr), tmp); e != nil {
return MakeCError(-1, 500, estr)
}
if tmp.Code == 0 {
return nil
}
if tmp.Httpcode == 0 {
tmp.Httpcode = 500
}
return tmp
} else {
//text format
index := strings.Index(estr, ",")
if index == -1 {
return MakeCError(-1, 500, estr)
}
p1 := estr[:index]
p2 := estr[index+1:]
if !strings.HasPrefix(p1, "code=") || !strings.HasPrefix(p2, "msg=") {
return MakeCError(-1, 500, estr)
}
code, e := strconv.ParseInt(p1[5:], 10, 32)
if e != nil {
return MakeCError(-1, 500, estr)
}
msg := p2[4:]
return MakeCError(int32(code), 500, msg)
}
}