emahiro/b.log

Drastically Repeat Yourself !!!!

cockroachdb/errors でスタックトレースを取得するのが良さそうだった

Overview

Go でエラーハンドリングするときにどこでエラーが発生したのかわかるように StackTrace を取得して、エラーメッセージと一緒に出力したいケースがあると思いますが、Go でStackTrace を取得するのはひと手間かかります。
「Go スタックトレース」といったキーワードでググると数多くの先人たちの知見をお目にかかる事ができますが、今回はそんな中でも cockroachdb/errors で Stack Trace を取得するのがお手軽で便利そうだったので、その備忘録です。

cockroachdb/errors とは

github.com

pkg.go.dev

cockroachdb が作ってる Go の errors のスーパーセットの中の一つで、スタックトレース以外にも便利な機能が用意されています。

スタークトレースの出力の仕方

pkg.go を見ればだいたい使い方はわかりますが、今回タイトルにおいているスタックトレースに絞った場合は以下のようにします。

// errors に stacktrace を追加する。
errors.WithStack(err)

// 追加した stacktrace に何かしらのメッセージを追加してエラーとして出力する。
errors.WithMessagef(errors.WithStack(err), format, args...)

スタックトレースのフォーマットは以下のように表示されます。

# サンプルの出力です。(今回は connect-go を使ってるプロジェクトでのスタックトレースを出力してみました。)

$ErrorMessage

(1) $Error Message
Wraps: (2) attached stack trace
  -- stack trace:
  | github.com/$ErrorMethod
  |     $ErrorFiles...
  | github.com/bufbuild/connect-go.NewUnaryHandler[...].func1
  |     /go/pkg/mod/github.com/bufbuild/connect-go@v1.9.0/handler.go:52
  | github.com/emahiro/qrurl/server/intercepter.NewRequestLogIntercepter.func1.1
  |     /app/intercepter/request_log_intercepter.go:25
  | github.com/bufbuild/connect-go.NewUnaryHandler[...].func2
  |     /go/pkg/mod/github.com/bufbuild/connect-go@v1.9.0/handler.go:81
  | github.com/bufbuild/connect-go.(*Handler).ServeHTTP
  |     /go/pkg/mod/github.com/bufbuild/connect-go@v1.9.0/handler.go:239
  | net/http.(*ServeMux).ServeHTTP
  |     /usr/local/go/src/net/http/server.go:2500
  | net/http.(*ServeMux).ServeHTTP
  |     /usr/local/go/src/net/http/server.go:2500
  | golang.org/x/net/http2/h2c.h2cHandler.ServeHTTP
  |     /go/pkg/mod/golang.org/x/net@v0.12.0/http2/h2c/h2c.go:125
  | github.com/rs/cors.(*Cors).Handler.func1
  |     /go/pkg/mod/github.com/rs/cors@v1.9.0/cors.go:236
  | net/http.HandlerFunc.ServeHTTP
  |     /usr/local/go/src/net/http/server.go:2122
  | net/http.serverHandler.ServeHTTP
  |     /usr/local/go/src/net/http/server.go:2936
  | net/http.(*conn).serve
  |     /usr/local/go/src/net/http/server.go:1995
  | runtime.goexit
  |     /usr/local/go/src/runtime/asm_amd64.s:1598
Wraps: (3) $ErrorEethod
Error types: (1) *hintdetail.withHint (2) *withstack.withStack (3) *errutil.leafError"

まとめ

Go で開発をしているとエラーハンドリングの中でも頭を悩ませるポイントが StackTrace だと思いますが。runtime package などを使って自前で作ることもありますが、cockroachdb/errors はスタックトレースのライブラリとしては有用なのではないかなと使ってみて感じました。

See Also

zenn.dev

tech.kanmu.co.jp