默认的错误处理是 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 alarmimport ("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 v1import ("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 mainimport ("fmt")func main() {fmt.Println("-- 1 --")defer func() {if r := recover(); r != nil {fmt.Printf("panic: %s\n", r)}fmt.Println("-- 2 --")}()panic("i am panic")}

输出:

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

无意抛出的 panic:

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

输出:

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

更多相关文章

  1. golang sqlx捕捉错误
  2. golang如何捕获错误
  3. golang panic可以捕获标准错误吗
  4. golang返回错误时如何正确处理
  5. golang怎么截获错误
  6. golang错误抛出的方法
  7. golang判断错误类型的方法
  8. golang怎么自定义错误
  9. go语言中一种常见的错误

随机推荐

  1. WPF实现好看的跑马灯特效实例
  2. 去重和排序如何操作
  3. C#串口通信的实例教程
  4. 分享关于asp注册代码实例
  5. EasyLoader(简单加载)实例
  6. bootstrap-multiselect 多选实例代码
  7. 详解可选参数和命名参数实例
  8. 分享一个IoC入门教程实例
  9. [转]Composite Keys With WebApi OData
  10. 总结EF通用数据层封装类实例详解