demo:
package main
import (
"context"
"net/http"
"github.com/gorilla/mux"
"github.com/pingcap/fn"
"github.com/pkg/errors"
)
var (
// ErrTest define an error
ErrTest = errors.New("test")
errs = map[error]int{
ErrTest: 1001,
}
)
// Unknown default error code
const Unknown = 1000
type statusCodeError struct {
err error
statusCode int
}
func (s *statusCodeError) StatusCode() int {
return s.statusCode
}
func (s *statusCodeError) Error() string {
return s.err.Error()
}
func (s *statusCodeError) Unwrap() error {
return s.err
}
// ErrorWithStatusCode Rewrite
func ErrorWithStatusCode(err error, statusCode int) error {
return &statusCodeError{err, statusCode}
}
// Error1 fn.ErrorWithStatusCode wrapped error cannot be unpacked to the original error
func Error1() (string, error) {
return "", fn.ErrorWithStatusCode(errors.WithStack(ErrTest), 500)
}
// Error2 ErrorWithStatusCode rewrite and implement the `StatusCode`, `Unwrap` interface to support the original error
func Error2() (string, error) {
return "", ErrorWithStatusCode(errors.WithStack(ErrTest), 500)
}
// Error3 The ErrorWithStatusCode error can no longer be set with a status code if it is wrapped.
func Error3() (string, error) {
return "", errors.WithStack(ErrorWithStatusCode(ErrTest, 500))
}
// Code 通过 error 获取 code 定义
func Code(err error) int {
code, ok := errs[err]
if !ok {
for err != nil {
err = errors.Unwrap(err)
code, ok = errs[err]
if ok {
return code
}
}
code = Unknown
}
return code
}
func main() {
// generate a response with a status code via error
fn.SetErrorEncoder(func(ctx context.Context, err error) interface{} {
code := Code(err)
return map[string]interface{}{
"code": code,
"message": err.Error(),
}
})
router := mux.NewRouter()
router.Handle("/error1", fn.Wrap(Error1))
router.Handle("/error2", fn.Wrap(Error2))
router.Handle("/error3", fn.Wrap(Error3))
server := &http.Server{
Addr: ":8080",
Handler: router,
}
server.ListenAndServe()
}
run server
test response
$ curl -i http://127.0.0.1:8080/error1
HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
Date: Thu, 27 Feb 2020 09:39:56 GMT
Content-Length: 31
{"code":1000,"message":"test"}
$ curl -i http://127.0.0.1:8080/error2
HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
Date: Thu, 27 Feb 2020 09:40:04 GMT
Content-Length: 31
{"code":1001,"message":"test"}
$curl -i http://127.0.0.1:8080/error3
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Thu, 27 Feb 2020 09:40:11 GMT
Content-Length: 31
{"code":1001,"message":"test"}
If possible I can submit a merge request to fix these issues
demo:
run server
test response
If possible I can submit a merge request to fix these issues