やる気がストロングZERO

やる気のストロングスタイル

Goのエラーハンドリングについて

したいこと

なにかエラーが出た時に、ログから

  • 「なにが発生したのか」
  • 「どこで発生したのか?」

がわかるようにしたい。

Go標準のerrorはスタックトレース情報を持ってない

errors.New("エラーメッセージ")

これだとスタックトレース情報がない。

エラーが出た時下記のようにして上位レイヤーでエラーログ出力する感じになると思うが、 これだと「どこで発生したのが?」が追えない。

// レイヤーの下の方でエラーがあったとする。
_, err := someFunc()
if err != nil {
  return err // 呼び出し元に返される
}

// 上位レイヤーでキャッチしてログ出力
err := underLayer()
if err != nil {
  logger.Error(err) //loggerが出力ファイル位置を吐き出すようにしてたとしても、あくまでこの位置なのでエラーの発生箇所がわからない。
}

なので、
https://github.com/pkg/errors
を使うことにした。(errorと同じインターフェースで使えて、スタックトレース情報を付加してくれる。)

使い方の指針

自分で作るエラーの場合

標準のerrorsの使い方と同じ。

import "github.com/pkg/errors"

err := errors.New("エラーメッセージ")

// こうやるとスタックトレース情報がとれる
fmt.Printf("%+v", err)

goの既存関数とかLibraryの関数が返してくるエラーの場合

既存関数(僕らが触れない部分)が返してくるエラーは標準のerrorsなのでスタックトレース情報を持ってない。
だから、下記の様にスタックトレース情報を付加してやる。

import "github.com/pkg/errors"

err := someFunc()
if err != nil {
  return errors.WithStack(err) // 呼び出し元に返される
}