Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Goのmultiple errorsについて (2024年4月版)
Search
syumai
April 23, 2024
Programming
14k
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
Workers Cache を知る
syumai
0
350
自分的「カンファレンスの楽しみ方」
syumai
0
220
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.6k
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
2.1k
Oxlintのカスタムルールの現況
syumai
6
2.1k
Oxlintはいかにしてtsgolintのlint ruleを呼び出しているのか
syumai
2
1.6k
『[入門] Cloudflare Workers』本はなぜ誕生したのか
syumai
0
650
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
9
3.4k
知られているようで知られていない JavaScriptの仕様 4選
syumai
3
1.3k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
630
APNsからLive Activityを開始する話
yumnumm
0
160
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
360
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
400
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
140
パスワード再設定メールのURLについて知っておこう
uyuki234
0
130
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.2k
TechTown - Creating Composable Callables in Contemporary C++
rollbear
0
100
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
240
Kubernetes祭り #2 OP/ED
bells17
0
110
Java 27新機能 / Java 27 new features
kishida
2
220
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
430
How to Talk to Developers About Accessibility
jct
2
570
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
YesSQL, Process and Tooling at Scale
rocio
174
15k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Fireside Chat
paigeccino
43
4.1k
The Language of Interfaces
destraynor
162
27k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
The untapped power of vector embeddings
frankvandijk
2
1.9k
Believing is Seeing
oripsolob
1
240
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
470
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
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 との互換対応済み