gitee.com/sasukebo/go-micro/v4@v4.7.1/errors/errors.go (about) 1 // Package errors provides a way to return detailed information 2 // for an RPC request error. The error is normally JSON encoded. 3 package errors 4 5 import ( 6 "encoding/json" 7 "errors" 8 "fmt" 9 "net/http" 10 ) 11 12 //go:generate protoc -I. --go_out=paths=source_relative:. errors.proto 13 14 func (e *Error) Error() string { 15 b, _ := json.Marshal(e) 16 return string(b) 17 } 18 19 // New generates a custom error. 20 func New(id, detail string, code int32) error { 21 return &Error{ 22 Id: id, 23 Code: code, 24 Detail: detail, 25 Status: http.StatusText(int(code)), 26 } 27 } 28 29 // Parse tries to parse a JSON string into an error. If that 30 // fails, it will set the given string as the error detail. 31 func Parse(err string) *Error { 32 e := new(Error) 33 errr := json.Unmarshal([]byte(err), e) 34 if errr != nil { 35 e.Detail = err 36 } 37 return e 38 } 39 40 // BadRequest generates a 400 error. 41 func BadRequest(id, format string, a ...interface{}) error { 42 return &Error{ 43 Id: id, 44 Code: 400, 45 Detail: fmt.Sprintf(format, a...), 46 Status: http.StatusText(400), 47 } 48 } 49 50 // Unauthorized generates a 401 error. 51 func Unauthorized(id, format string, a ...interface{}) error { 52 return &Error{ 53 Id: id, 54 Code: 401, 55 Detail: fmt.Sprintf(format, a...), 56 Status: http.StatusText(401), 57 } 58 } 59 60 // Forbidden generates a 403 error. 61 func Forbidden(id, format string, a ...interface{}) error { 62 return &Error{ 63 Id: id, 64 Code: 403, 65 Detail: fmt.Sprintf(format, a...), 66 Status: http.StatusText(403), 67 } 68 } 69 70 // NotFound generates a 404 error. 71 func NotFound(id, format string, a ...interface{}) error { 72 return &Error{ 73 Id: id, 74 Code: 404, 75 Detail: fmt.Sprintf(format, a...), 76 Status: http.StatusText(404), 77 } 78 } 79 80 // MethodNotAllowed generates a 405 error. 81 func MethodNotAllowed(id, format string, a ...interface{}) error { 82 return &Error{ 83 Id: id, 84 Code: 405, 85 Detail: fmt.Sprintf(format, a...), 86 Status: http.StatusText(405), 87 } 88 } 89 90 // Timeout generates a 408 error. 91 func Timeout(id, format string, a ...interface{}) error { 92 return &Error{ 93 Id: id, 94 Code: 408, 95 Detail: fmt.Sprintf(format, a...), 96 Status: http.StatusText(408), 97 } 98 } 99 100 // Conflict generates a 409 error. 101 func Conflict(id, format string, a ...interface{}) error { 102 return &Error{ 103 Id: id, 104 Code: 409, 105 Detail: fmt.Sprintf(format, a...), 106 Status: http.StatusText(409), 107 } 108 } 109 110 // InternalServerError generates a 500 error. 111 func InternalServerError(id, format string, a ...interface{}) error { 112 return &Error{ 113 Id: id, 114 Code: 500, 115 Detail: fmt.Sprintf(format, a...), 116 Status: http.StatusText(500), 117 } 118 } 119 120 // Equal tries to compare errors 121 func Equal(err1 error, err2 error) bool { 122 verr1, ok1 := err1.(*Error) 123 verr2, ok2 := err2.(*Error) 124 125 if ok1 != ok2 { 126 return false 127 } 128 129 if !ok1 { 130 return err1 == err2 131 } 132 133 if verr1.Code != verr2.Code { 134 return false 135 } 136 137 return true 138 } 139 140 // FromError try to convert go error to *Error 141 func FromError(err error) *Error { 142 if err == nil { 143 return nil 144 } 145 if verr, ok := err.(*Error); ok && verr != nil { 146 return verr 147 } 148 149 return Parse(err.Error()) 150 } 151 152 // As finds the first error in err's chain that matches *Error 153 func As(err error) (*Error, bool) { 154 if err == nil { 155 return nil, false 156 } 157 var merr *Error 158 if errors.As(err, &merr) { 159 return merr, true 160 } 161 return nil, false 162 } 163 164 func NewMultiError() *MultiError { 165 return &MultiError{ 166 Errors: make([]*Error, 0), 167 } 168 } 169 170 func (e *MultiError) Append(err *Error) { 171 e.Errors = append(e.Errors, err) 172 } 173 174 func (e *MultiError) HasErrors() bool { 175 return len(e.Errors) > 0 176 } 177 178 func (e *MultiError) Error() string { 179 b, _ := json.Marshal(e) 180 return string(b) 181 }