Go 語言的錯誤訊息處理
本文轉錄自: Go 語言的錯誤訊息處理
每個語言對於錯誤訊息的處理方式都不同,在學習每個語言時,都要先學會如何在程式內處理錯誤訊息 (Error Handler),而在 Go 語言的錯誤處理是非常簡單,本篇會用簡單的範例教大家 Go 如何處理錯誤訊息。
<!--more-->
Go 輸出錯誤訊息
在 Go 語言內有兩種方式讓函示 (function) 可以回傳錯誤訊息,一種是透過 errors
套件或 fmt
套件,先看看 errors 套件使用方式:
package main
import (
"errors"
"fmt"
)
func isEnable(enable bool) (bool, error) {
if enable {
return false, errors.New("You can't enable this setting")
}
return true, nil
}
func main() {
if _, err := isEnable(true); err != nil {
fmt.Println(err.Error())
}
}
請先引入 errors 套件,接著透過 errors.New("message here")
,就可以實現 error 錯誤訊息。接著我們開啟 errors package 原始碼來看看
package errors
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
可以發現 errors 套件內提供了 New
函示,讓開發者可以直接建立 error 物件,並且實現了 error interface。在 Go 語言有定義 error interface 為:
type error interface {
Error() string
}
只要任何 stuct
有實作 Error()
介面,就可以變成 error 物件。這在下面的自訂錯誤訊息會在提到。除了上面使用 errors 套件外,還可以使用 fmt 套件,將上述程式碼改成:
func isEnable(enable bool) (bool, error) {
if enable {
return false, fmt.Errorf("You can't enable this setting")
}
return true, nil
}
這樣也可以成功輸出錯誤訊息,請深入看 fmt.Errorf
為
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, a ...interface{}) error {
return errors.New(Sprintf(format, a...))
}
你可以發現在 fmt 套件內,引用了 errors 套件,所以基本上本質是一樣的。
Go 錯誤訊息測試
在 Go 語言如何測試錯誤訊息,直接引用 testing
套件
package error
import "testing"
func TestIsMyError(t *testing.T) {
ok, err := isEnable(true)
if ok {
t.Fatal("should be false")
}
if err.Error() != "You can't enable this setting" {
t.Fatal("message error")
}
}
另外 Go 語言最常用的測試套件 Testify,可以改寫如下:
package error
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsEnable(t *testing.T) {
ok, err := isEnable(true)
assert.False(t, ok)
assert.NotNil(t, err)
assert.Equal(t, "You can't enable this setting", err.Error())
}
Go 自訂錯誤訊息
從上面的例子可以看到,錯誤訊息都是固定的,如果我們要動態改動錯誤訊息,就必須帶變數進去。底下我們來看看如何實現自訂錯誤訊息:
package main
import (
"fmt"
)
// MyError is an error implementation that includes a time and message.
type MyError struct {
Title string
Message string
}
func (e MyError) Error() string {
return fmt.Sprintf("%v: %v", e.Title, e.Message)
}
func main() {
err := MyError{"Error Title 1", "Error Message 1"}
fmt.Println(err)
err = MyError{
Title: "Error Title 2",
Message: "Error Message 2",
}
fmt.Println(err)
}
也可以把錯誤訊息包成 Package 方式
package error
import (
"fmt"
)
// MyError is an error implementation that includes a time and message.
type MyError struct {
Title string
Message string
}
func (e MyError) Error() string {
return fmt.Sprintf("%v: %v", e.Title, e.Message)
}
在 main.go
就可以直接引用 error
套件
package main
import (
"fmt"
my "github.com/go-training/training/example04/error"
)
func main() {
err := my.MyError{"Error Title 1", "Error Message 1"}
fmt.Println(err)
err = my.MyError{
Title: "Error Title 2",
Message: "Error Message 2",
}
fmt.Println(err)
}
如何測試錯誤訊息是我們自己所定義的呢?請在 error 套件內加入底下測試函示
func IsMyError(err error) bool {
_, ok := err.(MyError)
return ok
}
由於我們實作了 error 介面,只要是 Interface 就可以透過 Type assertion 來判斷此錯誤訊息是否為 MyError
。
package error
import "testing"
func TestIsMyError(t *testing.T) {
err := MyError{"title", "message"}
ok := IsMyError(err)
if !ok {
t.Fatal("error is not MyError")
}
if err.Error() != "title: message" {
t.Fatal("message error")
}
}
這樣在專案裡就可以實現多個錯誤訊息,寫測試時就可以直接判斷錯誤訊息為哪一種自訂格式。
結論
在 Go 裡面寫錯誤訊息真的很方便又很容易,動態訊息請自定,反之,固定訊息請直接宣告 const 就可以了。在寫套件給大家使用時,大部份都是使用固定訊息,如果是大型專案牽扯到資料庫時,通常會用動態自訂錯誤訊息比較多。
上述程式碼請參考這裡
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go語言基礎-錯誤處理Go
- Go語言錯誤處理機制Go
- Go語言之錯誤處理Go
- Go語言(golang)的錯誤(error)處理的推薦方案GolangError
- 從錯誤處理看 Rust 的語言和 Go 語言的設計RustGo
- go的錯誤處理Go
- Go 錯誤處理Go
- 如何處理錯誤訊息PleaseinstalltheLinuxkernelheaderfilesLinuxHeader
- Go 語言異常處理Go
- Go 的錯誤處理策略 筆記Go筆記
- React應用裡Invalid hook call錯誤訊息的處理ReactHook
- CRM中介軟體裡parent not ok的錯誤訊息如何處理
- 如何處理Docker的錯誤訊息request canceled:Docker代理問題Docker
- 如何處理錯誤訊息Please install the gcc make perl packagesGCPackage
- go 錯誤處理設計思考Go
- Go 語言處理 yaml 檔案GoYAML
- go語言初學者常見錯誤Go
- 如何處理Docker錯誤訊息:please add——insecure-registryDocker
- 如何處理Eclipse錯誤訊息 The declared package does not match the expected packageEclipsePackage
- [譯] Go 1.13 errors 包錯誤處理GoError
- 開心檔之Go 錯誤處理Go
- Go 併發 2.2:錯誤處理模式Go模式
- Go語言中用於錯誤處理的Defer、Panic和Recover - Sachin KarveGo
- Go 語言操作 MySQL 之 預處理GoMySql
- 智慧合約語言 Solidity 教程系列9 - 錯誤處理Solid
- 如何處理錯誤訊息Please install the Linux kernel header filesLinuxHeader
- 如何處理SAP雲平臺錯誤訊息 there is no compute unit quota for subaccount
- 如何在 Go 中優雅的處理和返回錯誤(1)——函式內部的錯誤處理Go函式
- Go 語言中遇到 _func not exported by package_ 錯誤,應該如何處理?GoExportPackage
- 二、GO 程式設計模式:錯誤處理Go程式設計設計模式
- Go語言的表達性、錯誤處理方法和泛型等討論摘錄 - 駭客新聞Go泛型
- 寫給go開發者的gRPC教程-錯誤處理GoRPC
- go語言處理TCP拆包/粘包GoTCP
- GO語言手動處理TCP粘包GoTCP
- 如何處理VirtualBox啟動錯誤訊息:The vboxdrv kernel module is not loaded
- 三、訊息的可靠處理
- php ActiveMQ的傳送訊息,與處理訊息PHPMQ
- 錯誤處理