1.错误码定义
在errno包下定义,如下几个错误码
package errno
var(
OK=&Errno{Code: 0,Message: "OK"}
InternalServerError=&Errno{Code: 10001,Message: "Internal server error."}
ErrBind=&Errno{Code: 10002,Message: "Error occurred while binding the request body to the struct."}
ErrUserNotFound=&Errno{Code: 20102,Message: "The user was not found."}
)
复制代码
- Code:用来标识一个错误,可以看作ID
- Message: 用来显示具体的错误内容
2. 错误码设计
错误码分为三个部分
- 服务级错误(1位):1代表系统内部错误,2代表用户非法操作造成的错误
- 服务模块错误(2位):标识错误来自的服务模块
- 具体错误码(2位): 具体的错误标识
3. 错误信息处理
1. 定义两个结构体Errno,Err,并实现error接口方法
type Errno struct {
Code int
Message string
}
type Err struct {
Code int
Message string
Err error
}
func (err Errno)Error() string {//实现error接口方法
return err.Message
}
func (err *Err) Error() string {//实现error接口方法
return fmt.Sprintf("Err - code: %d, message: %s, error: %s", err.Code, err.Message, err.Err)
}
复制代码
2. 基于Errno结构体,去新建Err结构体
func New(errno *Errno,err error) *Err{
return &Err{Err: err,Code: errno.Code,Message: errno.Message}
}
复制代码
3. 定制Err结构体的message信息
func (err *Err) Add(message string) error {
err.Message+=" "+message
return err
}
func (err *Err) Addf(format string,args ...interface{}) error{
err.Message+=" "+fmt.Sprintf(format,args...)
return err
}
复制代码
4. 对传入的error进行解析,解析出该出错的出错码和出错信息
func IsErrUserNotFound(err error) bool {
decodeErr, _ := DecodeErr(err)
return decodeErr==ErrUserNotFound.Code
}
func DecodeErr(err error)(int,string) {
if err != nil {
return OK.Code,OK.Message
}
switch typed:=err.(type) {
case *Err:
return typed.Code,typed.Message
case *Errno:
return typed.Code,typed.Message
default:
}
return InternalServerError.Code,err.Error()
}
复制代码
errno.go 完整代码如下
package errno
import "fmt"
type Errno struct {
Code int
Message string
}
type Err struct {
Code int
Message string
Err error
}
func (err Errno)Error() string {//实现error接口方法
return err.Message
}
func (err *Err) Error() string {//实现error接口方法
return fmt.Sprintf("Err - code: %d, message: %s, error: %s", err.Code, err.Message, err.Err)
}
func New(errno *Errno,err error) *Err{
return &Err{Err: err,Code: errno.Code,Message: errno.Message}
}
func (err *Err) Add(message string) error {
err.Message+=" "+message
return err
}
func (err *Err) Addf(format string,args ...interface{}) error{
err.Message+=" "+fmt.Sprintf(format,args...)
return err
}
func IsErrUserNotFound(err error) bool {
decodeErr, _ := DecodeErr(err)
return decodeErr==ErrUserNotFound.Code
}
func DecodeErr(err error)(int,string) {
if err != nil {
return OK.Code,OK.Message
}
switch typed:=err.(type) {
case *Err:
return typed.Code,typed.Message
case *Errno:
return typed.Code,typed.Message
default:
}
return InternalServerError.Code,err.Error()
}
复制代码
4. 错误码测试
1. 用一个结构体绑定从接收到的json字符串,并且判断是否出错
var r struct{
Username string `json:"username"`
Password string `json:"password"`
}
var err error
if err:=c.Bind(&r); err!=nil{
c.JSON(http.StatusOK,gin.H{"error":errno.ErrBind})
return
}
复制代码
2. 对产生的错误进行解析,生成错误码
if r.Username==""{
err=errno.New(errno.ErrUserNotFound,fmt.Errorf("username can not found in db: xx.xx.xx.xx")).Add("This is add message.")
log.Printf("Get an error:%s",err)
}
if errno.IsErrUserNotFound(err){
log.Printf("err type is ErrUserNotFound")
}
if r.Password==""{
err=fmt.Errorf("password is empty")
}
code, message := errno.DecodeErr(err)
c.JSON(http.StatusOK,gin.H{"code":code,",message":message})
复制代码
完整代码如下:
package user
import (
"fmt"
"log"
"net/http"
"goPro/pkg/errno"
"github.com/gin-gonic/gin"
)
func Create(c *gin.Context) {
var r struct{
Username string `json:"username"`
Password string `json:"password"`
}
var err error
if err:=c.Bind(&r); err!=nil{
c.JSON(http.StatusOK,gin.H{"error":errno.ErrBind})
return
}
log.Printf("username is: [%s], password is [%s]", r.Username, r.Password)
if r.Username==""{
err=errno.New(errno.ErrUserNotFound,fmt.Errorf("username can not found in db: xx.xx.xx.xx")).Add("This is add message.")
log.Printf("Get an error:%s",err)
}
if errno.IsErrUserNotFound(err){
log.Printf("err type is ErrUserNotFound")
}
if r.Password==""{
err=fmt.Errorf("password is empty")
}
code, message := errno.DecodeErr(err)
c.JSON(http.StatusOK,gin.H{"code":code,",message":message})
}
复制代码
5. 样例测试
- post请求不带json字符串
- 只携带用户名
- 只携带密码
- 正常启动
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END