惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
B
Blog
博客园_首页
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
B
Blog RSS Feed
M
MIT News - Artificial intelligence
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
量子位
V
V2EX
Y
Y Combinator Blog
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
I
InfoQ
博客园 - 【当耐特】

博客园 - 基点项目师

dotweb now released to Version 1.5 dotweb框架之旅 [四] - 常用对象-HttpContext dotweb框架之旅 [三] - 常用对象-HttpServer dotweb框架之旅 [二] - 常用对象-App(dotweb) dotweb框架之旅 [一] - HelloWorld go服务端----使用dotweb框架搭建简易服务 对Golang有兴趣的朋友,推荐一款go语言Web框架-dotweb Nginx日志文件切割 linux安装PHP-memcache-redis扩展 微信公众平台开发 - 页面自适应 linux 安装 mongodb linux 安装 node.js nginx支持php配置 Linux 安装 php linux 安装nginx 如何设计自适应网页 ThinkDev.Data更新日志 ThinkDev.Logging-Queue模块介绍 Windows准备Node.js运行与开发环境
对 dotweb 框架进行统一的自定义错误处理
基点项目师 · 2017-06-07 · via 博客园 - 基点项目师

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