zoukankan      html  css  js  c++  java
  • 对 dotweb 框架进行统一的自定义错误处理

    golang近几年越来越火,尤其今年,我是一个不甘被抛弃的程序猿,因此在日常工作中,也开始使用go语言,Web框架主要使用dotweb框架,按照github上描述的主要特性如下:

    Features

    • 支持静态路由、参数路由、组路由
    • 路由支持文件/目录服务,支持设置是否允许目录浏览
    • 中间件支持,支持App、Group、Router级别的设置
    • Feature支持,可绑定HttpServer全局启用
    • 支持STRING/JSON/JSONP/HTML格式输出
    • 统一的HTTP错误处理
    • 统一的日志处理
    • 支持Hijack与websocket
    • 内建Cache支持
    • 支持接入第三方模板引擎(需实现dotweb.Renderer接口)
    • 模块可配置化,85%模块可通过配置维护

    今天我主要想说说最后一个特性里提到的,“统一的 HTTP 错误处理”。

    那么,在dotweb里如何优雅的处理呢? 

    我们先看下dotweb程序发生异常的时候,默认情况下,看会发生什么?

    package main
    
    import (
        "fmt"
        "github.com/devfeel/dotweb"
        "strconv"
    )
    
    func main() {
        //初始化DotServer
        app := dotweb.New()
    
        //开启development模式
        app.SetDevelopmentMode()
    
        //设置路由
        InitRoute(app.HttpServer)
    
        // 开始服务
        port := 8080
        fmt.Println("dotweb.StartServer => " + strconv.Itoa(port))
        err := app.StartServer(port)
        fmt.Println("dotweb.StartServer error => ", err)
    }
    
    func DefaultError(ctx dotweb.Context) error {
        panic("my panic error!")
    }
    
    func InitRoute(server *dotweb.HttpServer) {
        server.Router().GET("/error", DefaultError)
    }

    看看,访问会发生什么?

    ok。确实输出了我们的异常信息,不过下面跟着这么一大堆调用堆栈,明显是不能给用户看到的,参考其他Web容器,一般会返回用户一段:Internal Server Error

    这里可以通过将代码里的app.SetDevelopmentMode() 改为 app.SetProductionMode(),我们再看下访问结果:

    ok,满足我们的要求了。

    看到这里,大家是否觉得缺了点什么,就只能这么两种方式么?很明显,不是的:)

    我们总是希望一个框架能给我们足够的灵活性,足够的定制空间,顺着这个思路,我们来分析下。

    我们先看下dotweb的最核心的结构体定义:

    DotWeb struct {
            HttpServer       *HttpServer
            cache            cache.Cache
            OfflineServer    servers.Server
            Config           *config.Config
            Modules          []*HttpModule
            Middlewares      []Middleware
            ExceptionHandler ExceptionHandle
            NotFoundHandler  NotFoundHandle
            AppContext       *core.ItemContext
            middlewareMap    map[string]MiddlewareFunc
            middlewareMutex  *sync.RWMutex
        }

    果然,其中有一项:ExceptionHandler,进一步看下这个怎么定义的:

    ExceptionHandle func(Context, error)

    额,很简单有没有?果然很简单那!二话不说,我们赶紧来测试下。

    先做个简单测试,比如程序发生错误时,我们向用户输出一个 error 字符串,我们来看下怎么做:

    package main
    
    import (
        "fmt"
        "github.com/devfeel/dotweb"
        "strconv"
    )
    
    func main() {
        //初始化DotServer
        app := dotweb.New()
    
        //设置路由
        InitRoute(app.HttpServer)
    
        //设置自定义异常处理接口
        app.SetExceptionHandle(func(ctx dotweb.Context, err error) {
            ctx.WriteString("oh, 我居然出错了! ", err.Error())
        })
    
        // 开始服务
        port := 8080
        fmt.Println("dotweb.StartServer => " + strconv.Itoa(port))
        err := app.StartServer(port)
        fmt.Println("dotweb.StartServer error => ", err)
    }
    
    func DefaultError(ctx dotweb.Context) error {
        panic("my panic error!")
    }
    
    func InitRoute(server *dotweb.HttpServer) {
        server.Router().GET("/error", DefaultError)
    }

    访问下,会看到什么?

    一切顺利,输出了我们希望看到的内容。

    看到这里,大家是否有一个直观的印象?dotweb中,对于应用未处理的异常,只要通过设置SetExceptionHandle自定义处理函数,就可以对异常做你想做的任何事:)

    欢迎大家关注dotweb,一个成长中的go web框架。希望大家多给建议!

    github地址:https://github.com/devfeel/dotweb

    QQ群:193409346

  • 相关阅读:
    【CV论文阅读】Detecting events and key actors in multi-person videos
    2020意大利数学奥林匹克 第6题
    2020最终数学杯 初级组第3题
    地球上的最短距离
    钱学森做过的趣题
    第35届IMO预选题(瑞典提供)
    第55届IMO 第2题
    第四十届(1999年)IMO 第3题(白俄罗斯供题)
    2019年多瑙河数学竞赛(高中组) 第三题
    2020环球城市春季赛 O级别 高级组 第2题
  • 原文地址:https://www.cnblogs.com/pzrr/p/6957393.html
Copyright © 2011-2022 走看看