Goのエラー処理の基本について。
基本
エラー出力
errors.New関数を使用してエラーを表示します。
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("エラーだよ!!")
fmt.Println(err.Error()) // エラーだよ!! が表示される。
// 以下の方が一般的
//fmt.Println(err)
}
fmt.Errorf関数でも良いです。こちらは “%s” とか出力フォーマット関連の動詞が使用できます。
package main
import (
"fmt"
)
func main() {
err := fmt.Errorf("Error: %s", "エラーだよ!!")
fmt.Println(err) // Error: エラーだよ!! が表示される。
}
エラーのラッピング
エラーはエラーをラッピングする事ができます。
fmt.Errorf関数にて “%w” を使います。またラッピングされたエラー取得するにはUnwrap関数を使用します。
package main
import (
"errors"
"fmt"
)
func returnError() error {
orgErr := errors.New("オリジナルのエラーだよ")
return fmt.Errorf("エラーをラップしました。元のエラーは %w", orgErr)
}
func main() {
// ラップされたエラーを受け取る
reErr := returnError()
// エラーをアンラップしてオリジナルのエラーを取得する
orgErr := errors.Unwrap(reErr)
fmt.Println(orgErr) // オリジナルのエラーだよ が表示される
}
しかし、Unwrap関数を使うことはあまりありません。
カスタムエラー
エラーは自分で作成できます。
実態
errors.New関数やfmt.Errorf関数で受け取るerrの正体はerrorインターフェースの実装です。なので、errorインターフェースを実装すればカスタムエラーが作れます。
type error interface {
Error() string
}
実装
無理やりカスタムエラーを作成してみました。
package main
import (
"errors"
"fmt"
)
type MyError struct{}
func (em MyError) Error() string {
return "俺のエラー!!"
}
func returnError() error {
return fmt.Errorf("エラーをラップしました。元のエラーは %w", MyError{})
}
func main() {
// ラップされたエラーを受け取る
reErr := returnError()
// エラーをアンラップしてオリジナルのエラーを取得する
orgErr := errors.Unwrap(reErr)
fmt.Println(orgErr) // 俺のエラー!! が表示される
}