05-自定义接口的返回格式
HTTP错误返回结构自定义
- 默认返回处理: transport/http/codec.go
规范
-
- types.go 常见错误方法,判断错误
- wrap.go 标准错误包装,格式转换 AS
使用
安装包
# protoc-gen-go-errors go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest
编写
USER_NOT_FOUND = 0 [(errors.code) = 404];
运行
# 命令 make errors
结果
// 错误判断 func IsUserNotFound(err error) bool { if err == nil { return false } e := errors.FromError(err) return e.Reason == ErrorReason_USER_NOT_FOUND.String() && e.Code == 404 } // 错误封装,避免手写 func ErrorUserNotFound(format string, args ...interface{}) *errors.Error { return errors.New(404, ErrorReason_USER_NOT_FOUND.String(), fmt.Sprintf(format, args...)) }
代码
encoder.go
- 路径 internal\server\encoder.go
package server
import (
nethttp "net/http"
// "kratos-realworld/internal/errors"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/transport/http"
// "github.com/go-kratos/kratos/v2/transport/http"
)
/* 中间件调用 */
func errorEncoder(w nethttp.ResponseWriter, r *nethttp.Request, err error) {
se := errors.FromError(err)
codec, _ := http.CodecForRequest(r, "Accept")
body, err := codec.Marshal((se))
if err != nil {
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "application/"+codec.Name())
if se.Code > 99 && se.Code < 600 {
w.WriteHeader(int(se.Code))
} else {
w.WriteHeader(500)
}
_, _ = w.Write(body)
}
error_encoder.go
- internal\errors\error_encoder.go
package errors
import (
"fmt"
"github.com/go-kratos/kratos/v2/errors"
)
func NewHTTPError(code int, field string, detail string) *HTTPError {
return &HTTPError{
Code: code,
Errors: map[string][]string{
field: {detail},
},
}
}
type HTTPError struct {
Errors map[string][]string `json:"errors"`
Code int `json:"-"`
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTPError: %d", e.Code)
}
func FromError(err error) *HTTPError {
if err == nil {
return nil
}
if se := new(HTTPError); errors.As(err, &se) {
return se
}
// 修改错误格式
if se := new(errors.Error); errors.As(err, &se) {
return NewHTTPError(int(se.Code), se.Reason, se.Message)
}
return NewHTTPError(500, "internal", "error")
}