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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
56
自分的「カンファレンスの楽しみ方」
syumai
0
210
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.9k
Oxlintのカスタムルールの現況
syumai
6
2.1k
Oxlintはいかにしてtsgolintのlint ruleを呼び出しているのか
syumai
2
1.6k
『[入門] Cloudflare Workers』本はなぜ誕生したのか
syumai
0
600
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
9
3.3k
知られているようで知られていない JavaScriptの仕様 4選
syumai
3
1.3k
Other Decks in Programming
See All in Programming
一人だけ、Kiroが静止する日
hideg
0
120
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.9k
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
150
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
270
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
450
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
190
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
Building an Out-of-Order CPU
latte72
1
790
setup-vp GitLab対応の裏側
naokihaba
0
120
JRuby: Past, Present, and Future
headius
0
170
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
320
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.7k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
The untapped power of vector embeddings
frankvandijk
2
1.9k
For a Future-Friendly Web
brad_frost
183
10k
Become a Pro
speakerdeck
PRO
31
6.3k
Rails Girls Zürich Keynote
gr2m
96
14k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
470
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Paper Plane (Part 1)
katiecoart
PRO
2
11k
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 との互換対応済み