預設的錯誤處理是 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: %s\n", 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: %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 --
以上是golang gin框架錯誤處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!