Goにはスタックトレース機構がないので、どういう流れで処理が行われたのかが把握できない。
そのため、一番初めの呼び出し元にエラーをラップして戻す方法で、エラーの流れを把握する。
package main
import (
"errors"
"fmt"
)
type queryResult struct{}
func queryDatabase() (result *queryResult, err error) {
// なにかしらの処理をしたと仮定
// 一番最初のエラー
return result, errors.New("database is down")
}
func fetchData() (result *queryResult, err error) {
res, err := queryDatabase()
if err != nil {
// エラーをラップして返す
return &queryResult{}, fmt.Errorf("fetchData failed: %w", err)
}
return res, nil
}
func process() (result *queryResult, err error) {
res, err := fetchData()
if err != nil {
// エラーをラップして返す
return &queryResult{}, fmt.Errorf("process failed: %w", err)
}
return res, nil
}
func main() {
// 今までの処理のエラーがまとめて返ってくる
res, err := process()
if err != nil {
fmt.Println(err)
// 出力: process failed: fetchData failed: database is down
}
fmt.Println(res)
}
このようにすると、どういう流れで処理が行われ、どのようなエラーが起こったか把握できる。