可以使用panic造成异常,而不是层层往上返回错误,在recover中处理错误
//启动设置
app := iris.New()
app.Use(customRecover)
//处理逻辑
func customRecover(ctx iris.Context) {
defer func() {
if err := recover(); err != nil {
if ctx.IsStopped() {
return
}
var stacktrace string
for i := 1; ; i++ {
_, f, l, got := runtime.Caller(i)
if !got {
break
}
stacktrace += fmt.Sprintf("%s:%d\n", f, l)
}
ctx.StatusCode(200)
if ex, ok := err.(*commons.ErrorCode); ok {
//如果是业务异常,则返回业务异常信息
_, _ = ctx.JSON(ex.Error())
ctx.Application().Logger().Printf("[%d] %s\n%s", ex.Code, ex.Message, stacktrace)
} else {
//如果不是认为抛出的异常,统一包装为系统异常
_, _ = ctx.JSON(commons.ErrorCodeSystem)
errMsg := fmt.Sprintf("错误信息: %s", err)
// when stack finishes
logMessage := fmt.Sprintf("从错误中回复:('%s')\n", ctx.HandlerName())
logMessage += errMsg + "\n"
logMessage += fmt.Sprintf("\n%s", stacktrace)
// 打印错误⽇志
ctx.Application().Logger().Warn(logMessage)
}
// 返回错误信息
ctx.StopExecution()
}
}()
ctx.Next()
}
//应用层使用
func (this *articleService) FindArticlesByYearMonth(queryParam *commons.QueryParams, yearMonth string) (list []models.Article, paging *commons.Paging) {
//时间转时间戳
t, err := time.ParseInLocation("2006-01", yearMonth, time.Local)
if err != nil {
panic(commons.ErrorCodeParse)
}
}
package commons
import (
"encoding/json"
)
var (
ErrorCodeSystem = NewError(1000, "系统异常")
ErrorCodeNotLogin = NewError(1, "请先登录")
ErrorCodeParse = NewError(2, "解析错误")
ErrorCodeNotFound = NewError(3, "未找到")
ErrorCodeRegisterFailed = NewError(4, "用户注册失败")
)
func NewError(code int, text string) *ErrorCode {
return &ErrorCode{code, text, nil, false, nil}
}
func NewErrorData(code int, text string, errorData interface{}) *ErrorCode {
return &ErrorCode{code, text, nil, false, errorData}
}
func FromError(err error) *ErrorCode {
if err == nil {
return nil
}
return &ErrorCode{0, err.Error(), nil, false, nil}
}
type ErrorCode struct {
Code int
Message string
Data interface{}
Success bool
ErrorData interface{}
}
func (e *ErrorCode) Error() string {
marshal, _ := json.Marshal(e)
return string(marshal)
}