增加定时任务 处理异常

This commit is contained in:
2024-08-30 11:55:19 +08:00
parent aa3f9e8711
commit bfb284c4cc
30 changed files with 945 additions and 336 deletions

View File

@@ -1,4 +1,4 @@
package exception
package code
const (
SUCCESS = 1 // 操作成功
@@ -23,25 +23,3 @@ const (
DB_ERRROR = 10027 // 数据库错误
SENSITIVE = 10028 // 敏感词语
)
const (
//用户
NOT_FOUND_USER = 20001 // 未查询到用户
EXIST_USER = 20002 // 用户已存在
NO_BELONG_ACTION = 20003 // 越权操作
NO_PHONE = 20004 // 未验证手机号
//订单
ORDER_ERROR = 20100 // 订单统用错误
NO_ORDER = 20101 // 订单不存在
NO_PAID_ORDER = 20102 // 订单未支付
PAID_ORDER = 20103 // 订单已支付
EXPIRE_ORDER = 20104 // 订单超时
DONE_ORDER = 20105 // 订单已完结
NO_BELONG_ORDER = 20106 // 不属于自己的订单
//积分
SIGNED = 20200 // 已签到
NO_ENOUGH_POINT = 20201 // 积分不足
NO_ILLEGAL_CHANNEL = 20202 // 渠道非法
NO_ILLEGAL_SIGN = 20203 // 渠道非签到
)

View File

@@ -1,81 +1,164 @@
package exception
import (
"energy-management-system/utils"
"net/http"
"energy-management-system/utils/code"
"fmt"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"net/http"
)
type Exception struct {
HttpCode int `json:"-"`
Code int `json:"code"`
Msg interface{} `json:"msg"`
Err error `json:"err"`
type E struct {
Code int `json:"code"`
Msg any `json:"msg"`
Err error `json:"-"`
}
type ExceptionResponse struct {
Code int `json:"code"`
Msg interface{} `json:"msg"`
Path string `json:"path"`
}
func (r *Exception) Error() interface{} {
return r.Msg
}
func NotFoundR(c *gin.Context) {
c.JSON(http.StatusForbidden, ExceptionResponse{NOT_FOUND_ROUTE, "Not Found Route", utils.GetReqPath(c)})
}
func NotFoundM(c *gin.Context) {
c.JSON(http.StatusForbidden, ExceptionResponse{NOT_FOUND_METH, "Not Found Method", utils.GetReqPath(c)})
}
func Panic(c *gin.Context, e *Exception) {
c.JSON(e.HttpCode, ExceptionResponse{e.Code, e.Msg, utils.GetReqPath(c)})
}
func Unknow(c *gin.Context) {
c.JSON(http.StatusForbidden, ExceptionResponse{UNKNOW_ERROR, "未知错误", utils.GetReqPath(c)})
}
func Server(c *gin.Context) {
c.JSON(http.StatusInternalServerError, ExceptionResponse{SERVER_ERROR, "服务器错误", utils.GetReqPath(c)})
}
// FailMsg 主动抛出错误Exception类型
func FailMsg(msg interface{}) *Exception {
return &Exception{http.StatusOK, ERROR, msg, nil}
}
func FailCodeMsg(code int, msg string) *Exception {
return &Exception{http.StatusOK, code, msg, nil}
}
func PanicMsg(msg interface{}) {
PanicMsgBool(true, msg)
}
func PanicCodeMsg(code int, msg string) {
PanicCodeMsgBool(true, code, msg)
}
func PanicMsgBool(flag bool, msg interface{}) {
if flag {
panic(&Exception{http.StatusOK, ERROR, msg, nil})
}
}
func PanicCodeMsgBool(flag bool, code int, msg string) {
if flag {
panic(&Exception{http.StatusOK, code, msg, nil})
func (r E) Error() string {
if r.Err != nil {
return fmt.Sprintf(`{\"code\":%d;\"msg\":\"%v\",\"err\":\"%s\"}`, r.Code, r.Msg, r.Err.Error())
} else {
return fmt.Sprintf(`{\"code\":%d;\"msg\":\"%v\"}`, r.Code, r.Msg)
}
}
func PanicMsgErr(err error, msg interface{}) {
func (r E) Return(c *gin.Context) {
c.JSON(http.StatusOK, r)
}
func NE(msg any) error {
return NEC(msg, code.ERROR)
}
func NEC(msg any, code int) error {
return &E{
Msg: msg,
Code: code,
}
}
func NEE(err error, msg string) error {
return NEEC(err, msg, code.ERROR)
}
func NEEC(err error, msg string, code int) error {
if err != nil {
panic(&Exception{http.StatusOK, ERROR, msg, err})
return &E{
Msg: msg,
Code: code,
Err: err,
}
}
return nil
}
func PM(msg any) {
panic(&E{code.ERROR, msg, nil})
}
func PMC(msg any, code int) {
panic(&E{code, msg, nil})
}
func PBM(flag bool, msg any) {
if flag {
panic(&E{code.ERROR, msg, nil})
}
}
func PanicCodeMsgErr(err error, code int, msg string) {
func PBMC(flag bool, msg any, code int) {
if flag {
panic(&E{code, msg, nil})
}
}
func PEM(err error, msg any) {
if err != nil {
panic(&Exception{http.StatusOK, code, msg, err})
panic(&E{code.ERROR, msg, err})
}
}
func PEMC(err error, msg any, code int) {
if err != nil {
panic(&E{code, msg, err})
}
}
func PDM(db *gorm.DB, msgs ...string) {
if db.Error != nil {
msg := "未查询到"
if len(msgs) > 0 {
msg = msgs[0]
}
panic(&E{code.ERROR, msg, db.Error})
}
}
//type Exception struct {
// HttpCode int `json:"-"`
// Code int `json:"code"`
// Msg interface{} `json:"msg"`
// Err error `json:"err"`
//}
//
//type ExceptionResponse struct {
// Code int `json:"code"`
// Msg interface{} `json:"msg"`
// Path string `json:"path"`
//}
//
//func (r *Exception) Error() interface{} {
// return r.Msg
//}
//
//func NotFoundR(c *gin.Context) {
// c.JSON(http.StatusForbidden, ExceptionResponse{NOT_FOUND_ROUTE, "Not Found Route", utils.GetReqPath(c)})
//}
//
//func NotFoundM(c *gin.Context) {
// c.JSON(http.StatusForbidden, ExceptionResponse{NOT_FOUND_METH, "Not Found Method", utils.GetReqPath(c)})
//}
//
//func Panic(c *gin.Context, e *Exception) {
// c.JSON(e.HttpCode, ExceptionResponse{e.Code, e.Msg, utils.GetReqPath(c)})
//}
//func Unknow(c *gin.Context) {
// c.JSON(http.StatusForbidden, ExceptionResponse{UNKNOW_ERROR, "未知错误", utils.GetReqPath(c)})
//}
//func Server(c *gin.Context) {
// c.JSON(http.StatusInternalServerError, ExceptionResponse{SERVER_ERROR, "服务器错误", utils.GetReqPath(c)})
//}
//
//// FailMsg 主动抛出错误Exception类型
//func FailMsg(msg interface{}) *Exception {
// return &Exception{http.StatusOK, ERROR, msg, nil}
//}
//
//func FailCodeMsg(code int, msg string) *Exception {
// return &Exception{http.StatusOK, code, msg, nil}
//}
//
//func PanicMsg(msg interface{}) {
// PanicMsgBool(true, msg)
//}
//func PanicCodeMsg(code int, msg string) {
// PanicCodeMsgBool(true, code, msg)
//}
//
//func PanicMsgBool(flag bool, msg interface{}) {
// if flag {
// panic(&Exception{http.StatusOK, ERROR, msg, nil})
// }
//}
//func PanicCodeMsgBool(flag bool, code int, msg string) {
// if flag {
// panic(&Exception{http.StatusOK, code, msg, nil})
// }
//}
//
//func PanicMsgErr(err error, msg interface{}) {
// if err != nil {
// panic(&Exception{http.StatusOK, ERROR, msg, err})
// }
//}
//func PanicCodeMsgErr(err error, code int, msg string) {
// if err != nil {
// panic(&Exception{http.StatusOK, code, msg, err})
// }
//}

View File

@@ -0,0 +1,36 @@
package recovery
import (
"energy-management-system/core/logger"
"energy-management-system/global"
"energy-management-system/utils/code"
"energy-management-system/utils/exception"
"fmt"
)
func CronRecovery(name string) {
if err := recover(); err != nil {
var codes int
var msg any
var er error
if h, ok := err.(*exception.E); ok {
codes = h.Code
msg = h.Msg
er = h.Err
} else if e, ok := err.(error); ok {
msg = fmt.Sprint("未知错误:", e.Error())
logger.StackSend(5, e.Error())
codes = code.UNKNOW_ERROR
} else {
msg = fmt.Sprint("服务器错误:", err)
logger.StackSend(5, err.(string))
codes = code.SERVER_ERROR
}
global.Log.WithFields(map[string]any{
"code": codes,
"model": "task",
"func": name,
"err": er,
}).Error(msg)
}
}

View File

@@ -0,0 +1,86 @@
package recovery
import (
"energy-management-system/core/logger"
"energy-management-system/global"
"energy-management-system/utils"
"energy-management-system/utils/code"
"energy-management-system/utils/exception"
"github.com/gin-gonic/gin"
"net"
"net/http"
"os"
"strings"
)
func GinRecovery(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
var brokenPipe bool
if ne, ok := err.(*net.OpError); ok {
if se, ok := ne.Err.(*os.SyscallError); ok {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
brokenPipe = true
}
}
}
if brokenPipe {
c.Error(err.(error))
} else {
if req, ok := c.Get("_req"); ok {
global.Log.Errorln("获取参数:", utils.String(req))
}
if h, ok := err.(*exception.E); ok {
h.Return(c)
c.Errors = append(c.Errors, &gin.Error{Meta: h})
} else if e, ok := err.(error); ok {
global.Log.Errorln("未知错误:", err)
logger.StackSend(3, e.Error())
c.JSON(http.StatusForbidden, exception.E{code.UNKNOW_ERROR, "未知错误", nil})
} else {
global.Log.Errorln("服务器错误:", err)
logger.StackSend(3, err.(string))
c.JSON(http.StatusForbidden, exception.E{code.SERVER_ERROR, "服务器错误", nil})
}
}
c.Abort()
}
}()
c.Next()
}
//func GinRecovery() gin.HandlerFunc {
// return func(c *gin.Context) {
// defer func() {
// if err := recover(); err != nil {
// var brokenPipe bool
// if ne, ok := err.(*net.OpError); ok {
// if se, ok := ne.Err.(*os.SyscallError); ok {
// if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
// brokenPipe = true
// }
// }
// }
// if brokenPipe {
// c.Error(err.(error))
// } else {
// if h, ok := err.(*exception.Exception); ok {
// exception.Panic(c, h)
// c.Errors = append(c.Errors, &gin.Error{Meta: h})
// } else if _, ok = err.(error); ok {
// if gin.IsDebugging() {
// fmt.Printf("[Recovery] %s : %s", utils.TimeFormat(time.Now()), err)
// utils.Stack(3)
// }
// exception.Unknow(c)
// } else {
// fmt.Print(err)
// exception.Server(c)
// }
// }
// c.Abort()
// }
// }()
// c.Next()
// }
//}

179
utils/string.go Normal file
View File

@@ -0,0 +1,179 @@
package utils
import (
"encoding/json"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode"
)
func ReplaceDownLine(req string) (res string) {
for _, v := range req {
if 64 < v && v < 91 {
res = res + "_" + string(v+32)
} else {
res += string(v)
}
}
return strings.TrimRight(strings.TrimLeft(res, "_"), "_")
}
func String(data any) string {
if data == nil {
return ""
}
switch value := data.(type) {
case int:
return strconv.Itoa(value)
case int8:
return strconv.Itoa(int(value))
case int16:
return strconv.Itoa(int(value))
case int32:
return strconv.Itoa(int(value))
case int64:
return strconv.FormatInt(value, 10)
case uint:
return strconv.FormatUint(uint64(value), 10)
case uint8:
return strconv.FormatUint(uint64(value), 10)
case uint16:
return strconv.FormatUint(uint64(value), 10)
case uint32:
return strconv.FormatUint(uint64(value), 10)
case uint64:
return strconv.FormatUint(value, 10)
case float32:
return strconv.FormatFloat(float64(value), 'f', -1, 32)
case float64:
return strconv.FormatFloat(value, 'f', -1, 64)
case bool:
return strconv.FormatBool(value)
case string:
return value
case []byte:
return string(value)
case time.Time:
if value.IsZero() {
return ""
}
return value.String()
case *time.Time:
if value == nil {
return ""
}
return value.String()
default:
// Empty checks.
if value == nil {
return ""
}
var (
rv = reflect.ValueOf(value)
kind = rv.Kind()
)
switch kind {
case reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Func,
reflect.Ptr,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return ""
}
case reflect.String:
return rv.String()
}
if kind == reflect.Ptr {
return String(rv.Elem().Interface())
}
// Finally, we use json.Marshal to convert.
jsonContent, err := json.Marshal(value)
if err != nil {
return fmt.Sprint(value)
} else {
return string(jsonContent)
}
}
}
func IsNumber(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
func ContainChinese(str string) bool {
for _, r := range str {
if unicode.Is(unicode.Scripts["Han"], r) || (regexp.MustCompile("[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]").MatchString(string(r))) {
return true
}
}
return false
}
func Contains(ids []string, id string) bool {
for _, v := range ids {
if strings.Compare(v, id) == 0 {
return true
}
}
return false
}
// contain one of subs
func ContainSub(str string, subs ...string) bool {
for _, sub := range subs {
if strings.Contains(str, sub) {
return true
}
}
return false
}
// must contain all subs
func ContainSubs(str string, subs ...string) bool {
for _, sub := range subs {
if strings.Contains(str, sub) {
continue
} else {
return false
}
}
return true
}
func Duplicate(slc []string) []string {
result := make([]string, 0)
tempMap := make(map[string]bool, len(slc))
for _, e := range slc {
if tempMap[e] == false {
tempMap[e] = true
result = append(result, e)
}
}
return result
}
func Capitalize(str string) string {
var upperStr string
vv := []rune(str)
for i := 0; i < len(vv); i++ {
if i == 0 {
if vv[i] >= 97 && vv[i] <= 122 {
vv[i] -= 32 // string的码表相差32位
upperStr += string(vv[i])
} else {
return str
}
} else {
upperStr += string(vv[i])
}
}
return upperStr
}

View File

@@ -13,6 +13,21 @@ import (
"time"
)
func Exit(err any, str string) {
switch arg := err.(type) {
case error:
if arg != nil {
fmt.Println(str, arg.Error())
os.Exit(1)
}
case bool:
if arg {
fmt.Println(str, err)
os.Exit(1)
}
}
}
func GetReqPath(c *gin.Context) string {
return c.Request.Method + " " + c.Request.URL.String()
}