设为首页 加入收藏

TOP

[系列] Gin框架 - 自定义错误处理(四)
2019-07-25 14:17:27 】 浏览:287
Tags:系列 Gin 框架 定义 错误 处理
orString{text} }

那我们怎么捕获到呢?

使用中间件进行捕获,写一个 recover 中间件。

package recover

import (
    "fmt"
    "ginDemo/common/alarm"
    "github.com/gin-gonic/gin"
)

func Recover()  gin.HandlerFunc {
    return func(c *gin.Context) {
        defer func() {
            if r := recover(); r != nil {
                alarm.Panic(fmt.Sprintf("%s", r))
            }
        }()
        c.Next()
    }
}

路由调用中间件:

r.Use(logger.LoggerToFile(), recover.Recover())

//Use 可以传递多个中间件。

验证下吧,咱们先抛出两个异常,看看能否捕获到?

还是修改 product.go 这个文件吧。

有意抛出 panic:

package v1

import (
    "fmt"
    "ginDemo/entity"
    "github.com/gin-gonic/gin"
    "net/http"
)

func AddProduct(c *gin.Context)  {
    // 获取 Get 参数
    name := c.Query("name")

    var res = entity.Result{}

    str, err := hello(name)
    if err != nil {
        res.SetCode(entity.CODE_ERROR)
        res.SetMessage(err.Error())
        c.JSON(http.StatusOK, res)
        c.Abort()
        return
    }

    res.SetCode(entity.CODE_SUCCESS)
    res.SetMessage(str)
    c.JSON(http.StatusOK, res)
}

func hello(name string) (str string, err error) {
    if name == "" {
        // 有意抛出 panic
        panic("i am panic")
        return
    }
    str = fmt.Sprintf("hello: %s", name)
    return
}

访问:http://localhost:8080/v1/product/add

界面是空白的。

抛出了异常,输出信息如下:

{"time":"2019-07-23 22:42:37","alarm":"PANIC","message":"i am panic","filename":"绝对路径/ginDemo/middleware/recover/recover.go","line":13,"funcname":"1"}

很显然,定位的文件名、方法名、行号不是我们想要的。

需要调整 runtime.Caller(2),这个代码在 alarm.go 的 alarm 方法中。

将 2 调整成 4 ,看下输出信息:

{"time":"2019-07-23 22:45:24","alarm":"PANIC","message":"i am panic","filename":"绝对路径/ginDemo/router/v1/product.go","line":33,"funcname":"hello"}

这就对了。

无意抛出 panic:

// 上面代码不变

func hello(name string) (str string, err error) {
    if name == "" {
        // 无意抛出 panic
        var slice = [] int {1, 2, 3, 4, 5}
        slice[6] = 6
        return
    }
    str = fmt.Sprintf("hello: %s", name)
    return
}

访问:http://localhost:8080/v1/product/add

界面是空白的。

抛出了异常,输出信息如下:

{"time":"2019-07-23 22:50:06","alarm":"PANIC","message":"runtime error: index out of range","filename":"绝对路径/runtime/panic.go","line":44,"funcname":"panicindex"}

很显然,定位的文件名、方法名、行号也不是我们想要的。

将 4 调整成 5 ,看下输出信息:

{"time":"2019-07-23 22:55:27","alarm":"PANIC","message":"runtime error: index out of range","filename":"绝对路径/ginDemo/router/v1/product.go","line":34,"funcname":"hello"}

这就对了。

奇怪了,这是为什么?

在这里,有必要说下 runtime.Caller(skip) 了。

skip 指的调用的深度。

为 0 时,打印当前调用文件及行数。

为 1 时,打印上级调用的文件及行数。

依次类推...

在这块,调用的时候需要注意下,我现在还没有好的解决方案。

我是将 skip(调用深度),当一个参数传递进去。

比如:

// 发微信
func WeChat (text string) error {
    alarm("WX", text, 2)
    return &errorString{text}
}

// Panic 异常
func Panic (text string) error {
    alarm("PANIC", text, 5)
    return &errorString{text}
}

具体的代码就不贴了。

但是,有意抛出 Panic 和 无意抛出 Panic 的调用深度又不同,怎么办?

1、尽量将有意抛出的 Panic 改成抛出错误的方式。

2、想其他

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[系列] Gin框架 - 数据绑定和验证 下一篇go 接口

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目