美文网首页
iris的异常处理及返回统一自定义异常

iris的异常处理及返回统一自定义异常

作者: EasyNetCN | 来源:发表于2020-09-09 17:44 被阅读0次

    自定义异常结构体

    package model
    
    type BusinessException struct {
        Status  int    `json:"status"`
        Code    string `json:"code"`
        Message string `json:"message"`
        Trace   string `json:"trace"`
    }
    
    func (e *BusinessException) Error() string {
        return e.Trace
    }
    

    其中mvcApp.HandleError用来处理异常,app.OnAnyErrorCode用来返回自定义的结果

    package main
    
    import (
        "fmt"
        "io"
        "os"
        "strings"
        "time"
    
        _ "github.com/go-sql-driver/mysql"
        "github.com/hashicorp/consul/api"
        "github.com/kataras/iris/v12"
        "github.com/kataras/iris/v12/middleware/logger"
        "github.com/kataras/iris/v12/mvc"
        "xorm.io/xorm"
    
        "ydyun360.cn/member-service/configuration"
        "ydyun360.cn/member-service/controller"
        "ydyun360.cn/member-service/model"
        "ydyun360.cn/member-service/service"
    )
    
    /*
    读取本地配置
    读取Consul配置
    合并本地配置和Consul配置
    初始化数据库
    注册服务
    初始化组件和服务
    注册控制器
    初始化iris
    */
    
    const (
        LOG_DELETE_FILE_ON_EXIT = false
    )
    
    var (
        config        *configuration.SpringConfiguration
        consulClient  *api.Client
        registration  *api.AgentServiceRegistration
        orm           *xorm.Engine
        EXCLUDE_PATHS = [...]string{
            configuration.HEALTH_CHECK_URL,
        }
        EXCLUDE_EXTENSIONS = [...]string{
            ".js",
            ".css",
            ".jpg",
            ".png",
            ".ico",
            ".svg",
        }
    )
    
    var (
        syncService service.SyncService
    )
    
    func main() {
        initConfig()
    
        app := iris.Default()
    
        app.Use(iris.Gzip)
    
        mvcApp := mvc.New(app)
    
        mvcApp.HandleError(func(ctx iris.Context, err error) {
            file, line := ctx.HandlerFileLine()
    
            if ex, ok := err.(*model.BusinessException); ok {
                ctx.StatusCode(ex.Status)
                ctx.Values().Set("code", ex.Code)
                ctx.Values().Set("message", ex.Message)
                ctx.Values().Set("trace", fmt.Sprintf("%s:%d\n%s", file, line, ex.Message))
            } else {
                ctx.StatusCode(500)
                ctx.Values().Set("code", "")
                ctx.Values().Set("message", err.Error())
                ctx.Values().Set("trace", fmt.Sprintf("%s:%d\n%s", file, line, err.Error()))
            }
        })
    
        logFile := newLogFile()
    
        defer func() {
            logFile.Close()
    
            if LOG_DELETE_FILE_ON_EXIT {
                os.Remove(logFile.Name())
            }
        }()
    
        r := newRequestLogger(logFile)
    
        app.Use(r)
    
        app.OnAnyErrorCode(r, func(ctx iris.Context) {
            ctx.JSON(iris.Map{
                "status":  ctx.GetStatusCode(),
                "code":    ctx.Values().GetStringDefault("code", ""),
                "message": ctx.Values().GetStringDefault("message", ""),
                "trace":   ctx.Values().GetStringDefault("trace", "")})
        })
    
        iris.RegisterOnInterrupt(func() {
            fmt.Println("开始清理...")
    
            if err := consulClient.Agent().ServiceDeregister(registration.ID); err != nil {
                fmt.Printf("注销服务接异常 : %v\n", err)
            } else {
                fmt.Println("正常注销服务")
            }
    
            if err := orm.Close(); err != nil {
                fmt.Printf("关闭数据库链接异常 : %v\n", err)
            } else {
                fmt.Println("正常关闭数据库链接")
            }
    
            fmt.Println("完成清理...")
        })
    
        initService()
        initMvc(mvcApp)
    
        app.Listen(fmt.Sprintf(":%d", config.Server.Port), iris.WithOptimizations, iris.WithTimeFormat(config.DateTimeFormat))
    }
    
    func initConfig() {
        localConfig, err := configuration.ReadFromFile("bootstrap.yml")
    
        if err != nil {
            panic("读取本地配置文件bootstrap.yml发生异常")
        }
    
        consulClient, err = configuration.GetConsulClient(localConfig)
    
        if err != nil {
            panic("初始化Consul发生异常")
        }
    
        consulConfig, err := configuration.ReadFromConsul(consulClient, configuration.GetConsulConfigKey(localConfig))
    
        if err != nil {
            panic("读取Consul配置发生异常")
        }
    
        configuration.Merge(localConfig, consulConfig)
    
        orm, err = configuration.GetXormEngine(localConfig)
    
        if err != nil {
            panic("初始化数据库发生异常")
        }
    
        config = localConfig
    
        registration, err = configuration.RegisterConsul(consulClient, localConfig)
    
        if err != nil {
            panic("注册服务发生异常")
        }
    }
    
    func newRequestLogger(newWriter io.Writer) iris.Handler {
        c := logger.Config{}
    
        c.AddSkipper(func(ctx iris.Context) bool {
            path := ctx.Path()
    
            for _, p := range EXCLUDE_PATHS {
                if strings.HasPrefix(path, p) {
                    return true
                }
    
            }
    
            for _, ext := range EXCLUDE_EXTENSIONS {
                if strings.HasSuffix(path, ext) {
                    return true
                }
            }
            return false
        })
    
        c.LogFuncCtx = func(ctx iris.Context, latency time.Duration) {
            datetime := time.Now().Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
            message := ctx.Values().GetString("message")
    
            file, line := ctx.HandlerFileLine()
            source := fmt.Sprintf("%s:%d\n%s", file, line, message)
    
            jsonStr := fmt.Sprintf(`{"@timestamp":"%s","level":"%s","latency": "%s","ip":"%s""status": %d,"method":"%s","path":"%s","message":"%s"}`,
                datetime, "INFO", latency.String(), ctx.RemoteAddr(), ctx.GetStatusCode(), ctx.Method(), ctx.Path(), source)
    
            fmt.Fprintln(newWriter, jsonStr)
        }
    
        return logger.New(c)
    }
    
    func todayFilename() string {
        return fmt.Sprintf("%s.log", time.Now().Format(config.DateFormat))
    }
    
    func newLogFile() *os.File {
        path := "./logs"
        filename := fmt.Sprintf("%s/%s", path, todayFilename())
    
        if _, err := os.Stat(path); os.IsNotExist(err) {
            os.Mkdir(path, 0777)
            os.Chmod(path, 0777)
        }
    
        f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    
        if err != nil {
            panic(err)
        }
    
        return f
    }
    
    func initService() {
        syncService = service.NewSyncService(orm)
    }
    
    func initMvc(mvcApp *mvc.Application) {
        mvcApp.Party("/sync").Configure(sync)
    }
    
    func sync(app *mvc.Application) {
        app.Register(syncService)
        app.Handle(new(controller.SyncServiceController))
    }
    

    相关文章

      网友评论

          本文标题:iris的异常处理及返回统一自定义异常

          本文链接:https://www.haomeiwen.com/subject/nxfyektx.html