站长资讯网
最全最丰富的资讯网站

golang gin框架错误处理

golang gin框架错误处理

默认的错误处理是 errors.New("错误信息"),这个信息通过 error 类型的返回值进行返回。

推荐:golang教程

举个简单的例子:

func hello(name string) (str string, err error) { 	if name == "" { 		err = errors.New("name 不能为空") 		return 	} 	str = fmt.Sprintf("hello: %s", name) 	return }

当调用这个方法时:

var name = "" str, err :=  hello(name) if err != nil { 	fmt.Println(err.Error()) 	return }

这个默认的错误处理,只是得到了一个错误信息的字符串。

自定义错误处理

咱们定义一个 alarm.go,用于处理告警。

废话不多说,直接看代码。

package alarm  import ( 	"encoding/json" 	"fmt" 	"ginDemo/common/function" 	"path/filepath" 	"runtime" 	"strings" )  type errorString struct { 	s string }  type errorInfo struct { 	Time     string `json:"time"` 	Alarm    string `json:"alarm"` 	Message  string `json:"message"` 	Filename string `json:"filename"` 	Line     int    `json:"line"` 	Funcname string `json:"funcname"` }  func (e *errorString) Error() string { 	return e.s }  func New (text string) error { 	alarm("INFO", text) 	return &errorString{text} }  // 发邮件 func Email (text string) error { 	alarm("EMAIL", text) 	return &errorString{text} }  // 发短信 func Sms (text string) error { 	alarm("SMS", text) 	return &errorString{text} }  // 发微信 func WeChat (text string) error { 	alarm("WX", text) 	return &errorString{text} }  // 告警方法 func  alarm(level string, str string) { 	// 当前时间 	currentTime := function.GetTimeStr()  	// 定义 文件名、行号、方法名 	fileName, line, functionName := "?", 0 , "?"  	pc, fileName, line, ok := runtime.Caller(2) 	if ok { 		functionName = runtime.FuncForPC(pc).Name() 		functionName = filepath.Ext(functionName) 		functionName = strings.TrimPrefix(functionName, ".") 	}  	var msg = errorInfo { 		Time     : currentTime, 		Alarm    : level, 		Message  : str, 		Filename : fileName, 		Line     : line, 		Funcname : functionName, 	}  	jsons, errs := json.Marshal(msg)  	if errs != nil { 		fmt.Println("json marshal error:", errs) 	}  	errorJsonInfo := string(jsons)  	fmt.Println(errorJsonInfo)  	if level == "EMAIL" { 		// 执行发邮件  	} else if level == "SMS" { 		// 执行发短信  	} else if level == "WX" { 		// 执行发微信  	} else if level == "INFO" { 		// 执行记日志 	} }

看下如何调用:

package v1  import ( 	"fmt" 	"ginDemo/common/alarm" 	"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 == "" { 		err = alarm.WeChat("name 不能为空") 		return 	} 	str = fmt.Sprintf("hello: %s", name) 	return }

访问:http://localhost:8080/v1/product/add?name=a

{     "code": 1,     "msg": "hello: a",     "data": null }

未抛出错误,不会输出信息。

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

{     "code": -1,     "msg": "name 不能为空",     "data": null }

抛出了错误,输出信息如下:

{"time":"2019-07-23 22:19:17","alarm":"WX","message":"name 不能为空","filename":"绝对路径/ginDemo/router/v1/product.go","line":33,"funcname":"hello"}

panic 和 recover

当程序不能继续运行的时候,才应该使用 panic 抛出错误。

当程序发生 panic 后,在 defer(延迟函数) 内部可以调用 recover 进行控制,不过有个前提条件,只有在相同的 Go 协程中才可以。

有意抛出的 panic:

package main  import ( 	"fmt" )  func main() {  	fmt.Println("-- 1 --")  	defer func() { 		if r := recover(); r != nil { 			fmt.Printf("panic: %sn", r) 		} 		fmt.Println("-- 2 --") 	}() 	 	panic("i am panic") }

输出:

-- 1 -- panic: i am panic -- 2 --

无意抛出的 panic:

package main  import ( 	"fmt" )  func main() {  	fmt.Println("-- 1 --")  	defer func() { 		if r := recover(); r != nil { 			fmt.Printf("panic: %sn", r) 		} 		fmt.Println("-- 2 --") 	}()   	var slice = [] int {1, 2, 3, 4, 5}  	slice[6] = 6 }

输出:

-- 1 -- panic: runtime error: index out of range -- 2 --

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号