-
Notifications
You must be signed in to change notification settings - Fork 0
/
resp.go
155 lines (133 loc) · 3.21 KB
/
resp.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package miso
import (
"errors"
"fmt"
)
const (
ErrCodeGeneric = "XXXX"
)
type RespUnwrapper interface {
Unwrap() Resp
}
// Web Endpoint's Resp
type Resp struct {
ErrorCode string `json:"errorCode" desc:"error code"`
Msg string `json:"msg" desc:"message"`
Error bool `json:"error" desc:"whether the request was successful"`
Data interface{} `json:"data" desc:"response data"`
}
// Generic version of Resp
type GnResp[T any] struct {
ErrorCode string `json:"errorCode" desc:"error code"`
Msg string `json:"msg" desc:"message"`
Error bool `json:"error" desc:"whether the request was successful"`
Data T `json:"data" desc:"response data"`
}
func (r GnResp[T]) Unwrap() Resp {
return Resp{
ErrorCode: r.ErrorCode,
Msg: r.Msg,
Error: r.Error,
Data: r.Data,
}
}
func (r GnResp[T]) Err() error {
if r.Error {
return fmt.Errorf("Resp has error, code: %v, msg: %v", r.ErrorCode, r.Msg)
}
return nil
}
func (r GnResp[T]) Res() (T, error) {
return r.Data, r.Err()
}
func (r GnResp[T]) MappedRes(mapper map[string]error) (T, error) {
if r.Error {
if mapper != nil {
if err, ok := mapper[r.ErrorCode]; ok && err != nil {
return r.Data, err
}
}
return r.Data, r.Err()
}
return r.Data, r.Err()
}
func OkGnResp[T any](data T) GnResp[T] {
return GnResp[T]{
Data: data,
Error: false,
}
}
func WrapGnResp[T any](data T, err error) (GnResp[T], error) {
if err != nil {
return GnResp[T]{}, err
}
return OkGnResp(data), nil
}
// Wrap result (data and err) with a common Resp object.
//
// If err is not nil, returns a Resp body containing the error code and message.
// If err is nil, the data is wrapped inside a Resp object and returned with http.StatusOK.
func WrapResp(rail Rail, data interface{}, err error, url string) Resp {
if err != nil {
me := &MisoErr{}
if errors.As(err, &me) {
if !me.HasCode() {
me.Code = ErrCodeGeneric
}
if me.InternalMsg != "" {
rail.Infof("'%s' returned error, code: '%v', msg: '%v', internalMsg: '%v'", url, me.Code, me.Msg, me.InternalMsg)
} else {
rail.Infof("'%s' returned error, code: '%v', msg: '%v'", url, me.Code, me.Msg)
}
return ErrorRespWCode(me.Code, me.Msg)
}
ve := &ValidationError{}
if errors.As(err, &ve) {
msg := ve.Error()
rail.Infof("'%s' returned error, request invalid, msg: '%v'", url, msg)
return ErrorResp(msg)
}
// not a MisoErr, just return some generic msg
rail.Errorf("Unknown error, %v", err)
return ErrorResp("Unknown system error, please try again later")
}
return OkRespWData(data)
}
// Build error Resp
func ErrorResp(msg string) Resp {
return Resp{
ErrorCode: ErrCodeGeneric, // just some random code
Msg: msg,
Error: true,
}
}
// Build error Resp
func ErrorRespWCode(code string, msg string) Resp {
return Resp{
ErrorCode: code,
Msg: msg,
Error: true,
}
}
// Build OK Resp
func OkResp() Resp {
return Resp{
Error: false,
}
}
// Build OK Resp with data
func OkRespWData(data interface{}) Resp {
if data == nil {
return OkResp()
}
if v, ok := data.(Resp); ok {
return v
}
if v, ok := data.(RespUnwrapper); ok {
return v.Unwrap()
}
return Resp{
Data: data,
Error: false,
}
}