1. Error code definition
The following error codes are defined under the errno package
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."})Copy the code
- Code: Identifies an error. This can be considered an ID
- Message: Used to display specific error content
2. Error code design
The error code is divided into three parts
- Service-level error (1 bit) : 1 indicates an internal system error, and 2 indicates an error caused by illegal user operations
- Service module error (2 bits) : Identifies the service module from which the error came
- Specific error code (2 bits) : Indicates a specific error identifier
3. Error message processing
1. Define two structures Errno and Err, and implement error interface methods
type Errno struct {
Code int
Message string
}
type Err struct {
Code int
Message string
Err error
}
func (err Errno)Error(a) string {// Implement the error interface method
return err.Message
}
func (err *Err) Error(a) string {// Implement the error interface method
return fmt.Sprintf("Err - code: %d, message: %s, error: %s", err.Code, err.Message, err.Err)
}
Copy the code
2. Create an Err structure based on Errno
func New(errno *Errno,err error) *Err{
return &Err{Err: err,Code: errno.Code,Message: errno.Message}
}
Copy the code
3. Customize the Message message of the Err structure
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
}
Copy the code
4. Parse the error message to find the error code and error information
func IsErrUserNotFound(err error) bool {
decodeErr, _ := DecodeErr(err)
return decodeErr==ErrUserNotFound.Code
}
func DecodeErr(err error)(int.string) {
iferr ! =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()
}
Copy the code
Errno. Go the complete code is as follows
package errno
import "fmt"
type Errno struct {
Code int
Message string
}
type Err struct {
Code int
Message string
Err error
}
func (err Errno)Error(a) string {// Implement the error interface method
return err.Message
}
func (err *Err) Error(a) string {// Implement the error interface method
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) {
iferr ! =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()
}
Copy the code
4. Error code tests
1. Bind the RECEIVED JSON string with a structure and determine if there is an error
var r struct{
Username string `json:"username"`
Password string `json:"password"`
}
var err error
iferr:=c.Bind(&r); err! =nil{
c.JSON(http.StatusOK,gin.H{"error":errno.ErrBind})
return
}
Copy the code
2. Parse the error and generate an error code
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})
Copy the code
The complete code is as follows:
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
iferr:=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})
}
Copy the code
5. Sample test
- The POST request does not contain a JSON string
- Carry only the user name
- Carry only your password
- Normal boot