1、在主入口新增
package mainimport ("flag""fmt""go/application/internal/config""go/application/internal/handler""go/application/internal/middleware""go/application/internal/svc"manage "go/pkg/manage""github.com/zeromicro/go-zero/core/conf""github.com/zeromicro/go-zero/rest""github.com/zeromicro/go-zero/rest/httpx"
)var configFile = flag.String("f", "etc/service-api.yaml", "配置文件")func main() {flag.Parse()var c config.Config// 读取配置文件中的值,将其保存在c变量上 所以这一块传递的是地址conf.MustLoad(*configFile, &c)// 将全局配置保存在全局变量上config.GlobalConfig = c// 注册服务,传递服务配置server := rest.MustNewServer(c.RestConf)// 全局中间件 这儿主要用来捕获一下全局的异常,抛出给前端server.Use(middleware.WithMiddleware)// 停止服务defer server.Stop()// 为上下文赋值 将常用的方法绑定在上下文当中(redis、orm等等)ctx := svc.NewServiceContext(c)// 注册路由handler.RegisterHandlers(server, ctx)// 统一错误处理httpx.SetErrorHandler(manage.ErrHandler)fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)// 启动服务server.Start()
}
通过server.Use(middleware.WithMiddleware) 来注册一个全局中间件,接受一个函数
2、中间件函数体
package middlewareimport ("fmt"manage "go/pkg/manage""net/http"
)func WithMiddleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {defer func() {if err := recover(); err != nil {fmt.Println("============这儿是全局连接处理的异常===============")fmt.Println(err)fmt.Println("============这儿是全局连接处理的异常===============")manage.ResponseHandler(w, nil, &manage.ServerError)}}()next(w, r)}
}
通过defer和recover来捕获全局异常,如果出现异常,给前端返回500、服务器内部错误,并输出错误信息
3、向前端返回错误信息函数
manage->response.go
package manageimport ("net/http""github.com/zeromicro/go-zero/rest/httpx"
)type Body struct {Code int `json:"code"`Message string `json:"message"`Result interface{} `json:"data"`
}// 统一返回入口,
func ResponseHandler(w http.ResponseWriter, resp interface{}, err error) {if err != nil {httpx.OkJson(w, ErrHandler(err))// 如果err不为空的话,走错误处理函数,将err传递过去} else {// 没有错误信息,返回相应内容httpx.OkJson(w, Body{Code: OK.Code,Message: OK.Message,Result: resp,})}
}
manage->errorResponse.go
package managetype CodeError struct {Code int `json:"code"`Message string `json:"message"`
}// 实现error的接口 然后CodeError继承一下Error方法 CodeError就为error类型的返回值
func (e *CodeError) Error() string {return e.Message
}// 返回给前端的数据
func (e *CodeError) ErrorResponse() CodeError {return CodeError{Code: e.Code,Message: e.Message,}
}// 用来自定义抛出的异常,支持调用传递
func NewCodeError(code int, msg string) error {return &CodeError{Code: code,Message: msg,}
}// 提供new方法,任意地方传递参数返回CodeError类型的数据
func New(code int, msg string) CodeError {return CodeError{Code: code,Message: msg,}
}// 默认异常状态码函数,只需传递错误信息即可,默认返回code-10001
func DefaultErrHandler(message string) error {return &CodeError{Code: ServerError.Code,Message: message,}
}// 自定义错误返回函数 错误函数主入口
func ErrHandler(err error) interface{} {switch err.(type) {// 如果错误类型为CodeError,就返回错误类型的结构体case *CodeError:return errdefault:// 系统错误,500 错误提示return CodeError{Code: ServerError.Code, Message: err.Error()}}
}
manage->status.go
package managevar (OK = New(0, "操作成功")ReidsError = New(6379, "redis连接失败")JwtError = New(500, "JWT解密失败")TokenError = New(401, "Token已过期")ServerError = New(500, "服务器内部错误")
)
搞定收工