Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Goのmultiple errorsについて (2024年4月版)
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
syumai
April 23, 2024
Programming
13k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Goのmultiple errorsについて (2024年4月版)
syumai
April 23, 2024
More Decks by syumai
See All by syumai
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
Oxlintのカスタムルールの現況
syumai
6
1.1k
Oxlintはいかにしてtsgolintのlint ruleを呼び出しているのか
syumai
2
1.2k
『[入門] Cloudflare Workers』本はなぜ誕生したのか
syumai
0
380
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
9
3.1k
知られているようで知られていない JavaScriptの仕様 4選
syumai
3
1.2k
CloudflareのSandbox SDKを試してみた
syumai
0
870
実践AIチャットボットUI実装入門
syumai
9
4.2k
ProxyによるWindow間RPC機構の構築
syumai
3
1.5k
Other Decks in Programming
See All in Programming
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.1k
JavaDoc 再入門
nagise
1
360
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
350
Performance Engineering for Everyone
elenatanasoiu
0
140
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
6.4k
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
650
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
6
1.3k
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
250
Featured
See All Featured
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
160
Ruling the World: When Life Gets Gamed
codingconduct
0
250
Information Architects: The Missing Link in Design Systems
soysaucechin
0
970
We Are The Robots
honzajavorek
0
250
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
480
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
600
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
560
Java REST API Framework Comparison - PWX 2021
mraible
34
9.4k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
250
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Transcript
Go のmultiple errors について (2024 年4 月版) syumai Go のエラーハンドリング
最新事情Lunch LT (2024/4/23)
自己紹介 syumai Go Documentation 輪読会 ( 現在は不定期開催) / ECMAScript 仕様輪読会
主催 株式会社ベースマキナで管理画面のSaaS を開発中 Go でGraphQL サーバー (gqlgen) や TypeScript でフロント エンドを書いています Software Design 12 月号からCloudflare Workers の連載をして ます Twitter: @__syumai Website: https://syum.ai
None
ベースマキナとは? DB やAPI の接続設定 & 呼び出し設定をするだけで、簡単にUI 生成が行える管理画面 SaaS API 呼び出しへの権限設定や、レビュー依頼
/ 承認機能も簡単に使えます https://about.basemachina.com
本日話すこと multiple errors についえ multiple errors の基本的な使い方 multiple errors のユースケース
各ライブラリのmultiple errors の対応状況 multiple errors を扱うためのライブラリの紹介
mutiple errors について 本発表では、Go 1.20 で導入された Wrapping multiple errors の機能のことを指し
ます multiple errors と言う用語として何か定義されている訳ではないです https://go.dev/doc/go1.20#errors 複数のエラーをまとめて一つのエラーとして扱えるようにする機能です
multiple errors を扱うためのGo の機能 エラーを一つにまとめる機能 errors.Join fmt.Errorf の "%w" 一つにまとまったエラーを検証するための機能
errors.Is errors.As
エラーを一つにまとめる機能の使い方 errors.Join func A() error { return errorA } func
B() error { return errorB } func F() error { errA := A() errB := B() return errors.Join(errA, errB) }
エラーを一つにまとめる機能の使い方 fmt.Errorf func A() error { return errorA } func
B() error { return errorB } func F() error { errA := A() errB := B() return fmt.Errorf("errA: %w, errB: %w", errA, errB) }
一つにまとまったエラーを検証するための機能 errors.Is var ( errorA = errors.New("error A") errorB =
errors.New("error B") errorC = errors.New("error C") ) func F() error { errA := A() errB := B() return errors.Join(errA, errB) } func main() { err := F() fmt.Println(errors.Is(err, errorA)) // true fmt.Println(errors.Is(err, errorB)) // true fmt.Println(errors.Is(err, errorC)) // false }
一つにまとまったエラーを検証するための機能 errors.As type MyError struct{ Detail string } func (e
*MyError) Error() { ... } func main() { err := F() // return errors.Join(err1, err2) var myErr *MyError if errors.As(err, &myErr) { fmt.Println(myErr.Detail) } }
multiple errors を扱うライブラリを自作するには []error を返す Unwrap メソッドを実装したエラー型を作る type MyError struct
{ errs []error } func (e MyError) Unwrap []error { ... } func (e MyError) Error() string { ... }
multiple errors のユースケース defer errors.Join は nil を無視するので下記のように利用可能 func DoSomething()
(err error) { f, err := os.Open("somefile") if err != nil { return err } defer func() { closeErr := f.Close() // close がerror を返したら、F() の返したerror とJoin して返す err = errors.Join(err, closeErr) }() return F(f) }
multiple errors のユースケース 並行処理結果の待ち受け // https://pkg.go.dev/sync#WaitGroup の例 func FetchURLs() error
{ var wg sync.WaitGroup var urls = []string{ "http://golang.org/", "http://google.com/", "http://example.com/", } var errMu sync.Mutex var err error for _, url := range urls { wg.Add(1) go func(url string) { defer wg.Done() _, fetchErr := http.Get(url) errMu.Lock() err = errors.Join(err, fetchErr) // http.Get で発生した全てのエラーをまとめる errMu.Unlock() }(url) } wg.Wait() return err // まとめたエラーを返す }
サードパーティーライブラリのmultiple errors の対応状況 package status github.com/cockroachdb/errors O github.com/go-errors/errors O github.com/pkg/errors
X github.com/juju/errors X
cockroachdb/errors の例 func A() error { return errorA } func
B() error { return errorB } func F() error { errA := A() errB := B() return errors.Join(errA, errB) } func main() { err := F() fmt.Printf("%+v\n", err) // ちゃんとerror 全体のStacktrace が出る! }
cockroachdb/errors の例 (Stacktrace) // `fmt.Printf("%+v\n", err)` の出力結果 error A (1)
attached stack trace -- stack trace: | main.F | /Users/syumai/go/src/github.com/syumai/til/go/errors/multi-errors/join-cockroach/main.go:26 | main.main | /Users/syumai/go/src/github.com/syumai/til/go/errors/multi-errors/join-cockroach/main.go:30 | runtime.main | /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:271 Wraps: (2) error A | error B └─ Wraps: (3) attached stack trace -- stack trace: | main.init | /Users/syumai/go/src/github.com/syumai/til/go/errors/multi-errors/join-cockroach/main.go:11 | [...repeated from below...] └─ Wraps: (4) error B └─ Wraps: (5) attached stack trace -- stack trace: | main.init | /Users/syumai/go/src/github.com/syumai/til/go/errors/multi-errors/join-cockroach/main.go:10 | runtime.doInit1 | /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:7176 | runtime.doInit | /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:7143 | runtime.main | /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:253 | runtime.goexit | /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/asm_arm64.s:1222 └─ Wraps: (6) error A ...
go-errors/errors の例 func F() error { errA := A() errB
:= B() return errors.Join(errA, errB) } func main() { err := F() // fmt.Printf("%+v\n", err) // go-errors/errors は %+v でStacktrace を出力しない var goErr *errors.Error if errors.As(err, &goErr) { fmt.Println(goErr.ErrorStack()) // errors.As して取得する } }
go-errors/errors の例 (Stacktrace) 片方のerror のStacktrace しか表示されない // `fmt.Println(goErr.ErrorStack())` の出力結果 *errors.errorString
error A /Users/syumai/go/src/github.com/syumai/til/go/errors/multi-errors/join-go-errors/main.go:10 (0x104b579ec) init: errorA = errors.New("error A") /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:7176 (0x104b04a14) doInit1: f() /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:7142 (0x104af4fb4) doInit: for _, t := range ts { /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/proc.go:253 (0x104af4e9d) main: doInit(m.inittasks) /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/asm_arm64.s:1222 (0x104b241d4) goexit: MOVD R0, R0 // NOP
multiple errors を扱うためのライブラリ github.com/uber-go/multierr github.com/hashicorp/go-multierror 上記のいずれも、Go の標準ライブラリがmultiple errors をサポートする前から存在していた もの
Unwrap() []error サポート済みなので、標準ライブラリとの互換性もあります 標準ライブラリのerrors には存在しない機能もあるので興味があれば見てみてください (multiple errors 特化なので、使いどころは選びます)
まとめ Go 1.20 でmultiple errors がサポートされた サードパーティーライブラリでのmultiple errors 対応状況はそれぞれ異なる その上で、Stacktrace
の対応状況も異なる 以前から存在するmultiple errors を扱うためのライブラリは、標準ライブラリのerrors との互換対応済み