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
410
自分的「カンファレンスの楽しみ方」
syumai
0
230
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.6k
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
2.2k
Oxlintのカスタムルールの現況
syumai
6
2.2k
Oxlintはいかにしてtsgolintのlint ruleを呼び出しているのか
syumai
2
1.7k
『[入門] Cloudflare Workers』本はなぜ誕生したのか
syumai
0
680
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
9
3.4k
知られているようで知られていない JavaScriptの仕様 4選
syumai
3
1.3k
Other Decks in Programming
See All in Programming
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
140
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
280
React Native経験者が Flutterを30⽇間触って驚いたこと
3saito
0
150
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
180
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
290
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
120
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
200
AWS CDKを理解するために公式の定義を深掘って解説してみる / Understanding AWS CDK by Digging into Its Official Definition
akihisaikeda
2
260
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
220
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
290
Getting Started with Vibe Coding
miccheng
0
180
高橋メソッドでCVE解説シリーズ 〜CVE-2026-112816〜
hakkadaikon
0
210
Featured
See All Featured
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Practical Orchestrator
shlominoach
192
12k
Speed Design
sergeychernyshev
33
2.2k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
500
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Fireside Chat
paigeccino
43
4.1k
Become a Pro
speakerdeck
PRO
31
6.3k
It's Worth the Effort
3n
188
29k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
450
Designing for Timeless Needs
cassininazir
1
550
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
760
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 との互換対応済み