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
エラー処理の温故知新 / history of error handling technic
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
nakaryo
May 01, 2026
Programming
2k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
エラー処理の温故知新 / history of error handling technic
nakaryo
May 01, 2026
More Decks by nakaryo
See All by nakaryo
Ruby で gRPC を使おう / ruby-grpc
ryotanakaya
1
140
ギフティの技術ブログ 再出発とこれから / restart of giftee tech blog 2024
ryotanakaya
0
360
再利用パターン / Pattern of code reuse
ryotanakaya
0
200
エンジニアリングエッセイのススメ
ryotanakaya
0
510
ソフトウェアアーキテクチャについて 語るときに 僕の語ること
ryotanakaya
2
1.7k
エンジニアと要件定義
ryotanakaya
4
1.2k
Go と並行処理
ryotanakaya
0
420
ワクワク!Rubyクイズ!!
ryotanakaya
0
1.6k
増え続けるトランザクションデータと向き合う
ryotanakaya
0
550
Other Decks in Programming
See All in Programming
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
170
Oxlintのカスタムルールの現況
syumai
6
1.2k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
270
Inside Stream API
skrb
1
800
dRuby over BLE
makicamel
2
390
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
240
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
190
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
Performance Engineering for Everyone
elenatanasoiu
0
230
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
810
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
470
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
180
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
96
14k
Marketing to machines
jonoalderson
1
5.5k
WCS-LA-2024
lcolladotor
0
660
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
210
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Making the Leap to Tech Lead
cromwellryan
135
9.9k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Designing Experiences People Love
moore
143
24k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Chasing Engaging Ingredients in Design
codingconduct
0
230
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
Transcript
エラー処理の温故知新 エラー処理の温故知新 エラー処理の温故知新 エラー処理の温故知新 Nakaya Ryota 2026.05.01 giftee TechBash 1
自己紹介 なかりょー @ 株式会社ギフティ バックエンドエンジニア ▸ 前職はバックオフィス ERP ベンダーで上流メイン ▸
Go / Ruby / Java ▸ AI に翻弄される今日この頃 ▸ 2
みなさん、エラー処理やってますか? 3
プログラムは必ず失敗する 人間と同じで、プログラムも必ず失敗する ▸ ファイルがない ▫ ネットワークが落ちる ▫ 入力値が不正 ▫ NULL
ポインター ▫ 型が食い違う ▫ etc... ▫ 様々な理由でエラーは発生する ▸ 4
そもそもエラーとは何か エラーとは、プログラムの期待と現実のギャップである ▸ 「このファイルは存在するはず」 → なかった ▫ 「この値は正の整数のはず」 → 負の値だった
▫ 「このサーバーは応答するはず」 → タイムアウトした ▫ つまり、プログラムが置いた前提や仮定が崩れた瞬間がエラー ▸ 前提は必ずどこかで崩れる — だからエラー処理が必要になる ▸ 5
ドメインエラー vs 非ドメインエラー ドメインエラー 非ドメインエラー 入力値が不正 ▸ 実行の前提条件が満たされていない ▸ 認証・認可の失敗
▸ etc ▸ メモリ不足(OOM ) ▸ ネットワーク障害 ▸ NULL ポインター参照 ▸ etc ▸ 6
エラーハンドリング、どう書いていますか? 各言語がどんな答えを出してきたのか、歴史を振り返りながら考えてみましょう プログラムを書くとは、エラーハンドリングを書くことでもある ▸ 皆さんはエラーハンドリングをどのように書いていますか? どのようなことを意識していますか? ▸ Ruby だと Exception
を使うのが常識になっていますよね? ▸ Exception を体系的に設計できていますか? ▫ 7
C 言語の時代 8
C 言語の時代 — エラーは値だった if (open(...) < 0) { perror("open");
} C 言語と Unix 哲学の世界 ▸ エラーというのは値だった → プログラムのロジックで処理するもの ▸ 関数やプログラムは成功・失敗を数値で表現する ▸ 0 なら正常、0 以外なら異常 ▫ ✔ シンプル ▸ ✘ 戻り値をチェックし忘れるリスクがある ▸ ✘ 正常系と異常系が混ざる ▸ 9
Exception の時代 10
Exception の時代 try { readFile(); } catch (IOException e) {
... } C++ 、Java 、Python 、Ruby など現代主流の言語に見られる ▸ 例外機構自体はもっと以前からあったが、90 年代の言語が普及に寄与 ▫ ✔ 正常系と異常系のフローを分けて書ける ▸ ✔ 大域脱出するため、チェック漏れのリスクがない ▸ 11
Exception の課題 どこでどういう例外が発生するのかを把握するのが難しい ▸ 関数定義をパッと見ただけではわからない ▫ プログラム全体を見ないと、どこで何がハンドリングされているのかわからない ▫ → 設計難易度が高い
▫ 結果、別の形のリスクが生まれる ▸ スローされたまま誰もキャッチしない ▫ 意図せず握りつぶされる ▫ 12
Java の検査例外 void foo() { bar(); // HogeException をキャッチするかスローしないとコンパイルエラー }
void bar() throws HogeException { ... } ✘ コンパイルエラー — foo() は HogeException を処理していない 関数がどういう例外をスローしうるかをシグネチャで表現する ▸ 13
Java の検査例外 — 正しい記述 A. キャッチして処理する void foo() { try
{ bar(); } catch (HogeException e) { // ここで回復処理 } } B. スローを伝播する void foo() throws HogeException { bar(); // 呼び出し元に責任を委譲 } どちらかを選ばないとコンパイルが通らない → 処理漏れを防ぐ ▸ 14
検査例外のトレードオフ 伝播コストがかかる ▸ 全員がキャッチ・スローを書いて伝播させなければならない ▫ ラップしてリスローするコードが至るところに生まれる ▫ API 変更に弱い ▸
例外の種類を増やすと、呼び出し側全員がキャッチを書く必要がある ▫ 高階関数やラムダ式、関数型記法との相性が悪い ▫ 失敗可能性を明示することと、失敗から回復できることは別問題だった ▸ 15
現代の別解:Go のエラーハンドリング 16
技術の進化は螺旋 f, err := os.Open("file.txt") if err != nil {
return err } 2009 年に生まれた Go は、エラーを値として返すという 古典的な方法をあえて選んだ ▸ 17
Go の思想 "Errors are values (エラーは値である)" — Rob Pike go.dev/blog/errors-are-values
- Why does Go not have exceptions? — Go FAQ - 「例外」がないからGo 言語はイケてないとかって言ってるヤツが本当にイケてない件 例外は使わない(panic はあるけど、回復不能な異常時のみ) ▸ エラーは「摩訶不思議なもの」でも「例外的なもの」でもない ▸ ファイルがない・入力値がおかしいのは日常的な事象 ▫ だから特別な制御構造(例外)ではなく、通常の値として扱うべき ▫ 常にその場で処理するか、呼び出し元に返す ▸ 「魔法を減らせ」 ▸ 18
なぜ値リターンに戻ったのか Exception はシグネチャに現れず、どこで何が飛ぶかわからない ▸ デバッグが難しい — throw 元と catch 先が離れがち
▸ "Cleaner, more elegant, and wrong" — Raymond Chen ▫ 制御フローが追いにくい — 暗黙の大域脱出が隠れている ▸ ドメインエラーと非ドメインエラーの使い分け ▸ ドメインエラー:予期される事象 → 制御構造(ロジック)で扱う ▫ 非ドメインエラー(OOM, NPE ) :制御できない → 大域脱出 ▫ 異なる性質の事象なので、対処方法を明示的に使い分ける ▫ そもそも goto 文はマジカルでよくないと教わったのに、 例外だけ例外的に扱うのどうなん? ▸ 19
オフトピック:Clean Code の見解 『Clean Code 』の中でボブおじは、 値リターンはコードの可読性を下げるからお勧めしないと書いている ▸ 正常系がストレートに読める方がコードの意図が掴みやすい ▸
ただし、イディオムの違いによる可読性は宗教論争になりがちで、 これもご多分に漏れない ▸ 20
エラーを型で扱う時代 21
エラーを型で扱う fn read_file() -> Result<String, Error> Rust 、Haskell 、Scala 、Swift
、Kotlin など ▸ 成功すれば String が、失敗すれば Error が返る。それ以外はありえない ▸ 失敗する可能性が型に現れる ▸ 値(データ)ではなく型(プログラムの構造)として表現 ▫ 値はハンドリングしなくても良いが、型はハンドリングを強制する ▫ 22
値として扱う vs 型として扱う Go — 値は無視できる f, err := os.Open("file.txt")
// err を無視しても // コンパイルは通る doSomething(f) Rust — 型は強制する let result = read_file(); // Result を開かないと // 中身を使えない do_something(result); // 型エラー 値はチェックするもしないも開発者の自己責任 ▸ 型はコンパイラが処理を強制する — うっかり無視できない ▸ 23
Result 型のハンドリング match read_file() { Ok(content) => println!("{}", content), Err(e)
=> eprintln!("Error: {}", e), } match で全パターンを網羅しないとコンパイルエラー ▸ Ok だけ書いて Err を省略 → コンパイルエラー ▸ 「処理し忘れ」がそもそも起こりえない構造になっている ▸ ただし、意図的に捨てることは可能( let _ = read_file(); ) ▸ Java の検査例外と違い、どの階層で処理するかは開発者が自由に選べる ▸ 24
型によるエラー表現の特徴 うっかり無視はできないが、意図的に捨てることはできる ▸ Java の検査例外:各階層に「処理 or 宣言」を強制 ▫ Rust の
Result :失敗の可能性を示すが、どこで処理するかは自由 ▫ ✔ コンパイラが処理漏れを検出できる — 例外より明示的 ▸ ✔ エラーを合成でき、関数型とも相性が良い ▸ ✘ 記述量は増えることもある ▸ 25
まとめ エラー処理に銀の弾丸はない — だからこそ面白い エラー処理の仕組みと思想は言語ごとに異なる ▸ 最近の言語トレンドはエラーを型で表現する方向へ ▸ それぞれの特性を理解して、正しく向き合おう ▸
26