Slide 1

Slide 1 text

© 2024 Finatext Holdings Ltd. Error Handling in Rust Applications Taiki Ono, Finatext

Slide 2

Slide 2 text

© 2024 Finatext Holdings Ltd. Taiki Ono @taiki45 1

Slide 3

Slide 3 text

© 2024 Finatext Holdings Ltd. アプリケーションを書くことはエラーハンドリングを書く と言っても…過言ですすみません 2

Slide 4

Slide 4 text

© 2024 Finatext Holdings Ltd. 自動化: なにかエラーが起きてもリトライとかで回復できるものなら自動で復旧できる 可視化: 「なにが原因でエラーなのか」「回避・復旧するためのアクションはなにか」をソフトウェアのユーザー に伝える。 良いコードはエラーの内容を見ただけで回避・復旧のアクションができる。悪いコードはコードを読まないと エラーの原因や復旧手段がわからない。 エラーハンドリングで目指すところ 3

Slide 5

Slide 5 text

© 2024 Finatext Holdings Ltd. ほとんど層では下層のエラーをラップして上層に投げ返す →anyhow crate 一部の層(特に下層)では特定のエラー状況に対して追加で処理をしたり条件分岐する →thiserror crate アプリケーションでのエラーハンドリング 4

Slide 6

Slide 6 text

© 2024 Finatext Holdings Ltd. 主にanyhow::Error struct提供するcrate。他にも便利関数やマクロが盛りだくさん anyhow::Error ≒ Box ● std::error::Errorはtrait ● dyn Traitはtrait objects ● 参照(e.g. Box)越しに動的に異なる値を扱う 実際はanyhow::Result経由で使う anyhow crate 5

Slide 7

Slide 7 text

© 2024 Finatext Holdings Ltd. anyhow::Result 6

Slide 8

Slide 8 text

© 2024 Finatext Holdings Ltd. anyhow::Context 7

Slide 9

Slide 9 text

© 2024 Finatext Holdings Ltd. anyhow::Context 8

Slide 10

Slide 10 text

© 2024 Finatext Holdings Ltd. anyhow::Context 9

Slide 11

Slide 11 text

© 2024 Finatext Holdings Ltd. anyhow::Context 10

Slide 12

Slide 12 text

© 2024 Finatext Holdings Ltd. anyhow::Context and Option 11 anyhowがOptionに対してもContext traitをimplしてくれているので、Optionに対してもwith_contextが使え る。with_contextはanyhow::Resultを返すので `?` オペレーターで上流に返せる これとunwrap_or_*系を使うとunwrapを消せるのでunwrap系のlintを有効にできて平穏

Slide 13

Slide 13 text

© 2024 Finatext Holdings Ltd. anyhow::bail! 12 `return Err(anyhow::Error)` を短く書ける

Slide 14

Slide 14 text

© 2024 Finatext Holdings Ltd. エラーメッセージのスタイル 13 A. "Failed to read!" B. "failed to read!" C. "Failed to read" D. "failed to read"

Slide 15

Slide 15 text

© 2024 Finatext Holdings Ltd. エラーメッセージのスタイル 14 ✅ (D) "failed to read" >Error messages are typically concise lowercase sentences without trailing punctuation https://doc.rust-lang.org/std/error/trait.Error.html

Slide 16

Slide 16 text

© 2024 Finatext Holdings Ltd. Downcasting with anyhow 15

Slide 17

Slide 17 text

© 2024 Finatext Holdings Ltd. thiserror crate 16

Slide 18

Slide 18 text

© 2024 Finatext Holdings Ltd. Iterator::try_fold 17 コレクションの中身をイテレートしつつ要素1つ1つに失敗する可能性があるオペレーションをする時に便利

Slide 19

Slide 19 text

© 2024 Finatext Holdings Ltd. Iterator::try_fold 18

Slide 20

Slide 20 text

© 2024 Finatext Holdings Ltd. aws-lambda-runtime v0.12 upgrade ケーススタディ 19

Slide 21

Slide 21 text

© 2024 Finatext Holdings Ltd. ケーススタディ: aws-lambda-runtime v0.12 upgrade 20 `impl Future>` を返すいたって普通のクロージャー

Slide 22

Slide 22 text

© 2024 Finatext Holdings Ltd. v0.12に上げたらコンパイルエラー 21

Slide 23

Slide 23 text

© 2024 Finatext Holdings Ltd. v0.12に上げたらコンパイルエラー 22 https://minne.com/items/2715511

Slide 24

Slide 24 text

© 2024 Finatext Holdings Ltd. コンパイルエラー 23 anyhow::ErrorがIntoを実装してない Diagnostic…誰?

Slide 25

Slide 25 text

© 2024 Finatext Holdings Ltd. trait bounds of the `run` function 24

Slide 26

Slide 26 text

© 2024 Finatext Holdings Ltd. Before v0.12 25 v0.12以前ではDisplayさえ実装していればblanket implementationによってDiagnosticへの変換も実装されて いた

Slide 27

Slide 27 text

© 2024 Finatext Holdings Ltd. After v0.12 26 v0.12以降ではstd::error::Error系のみblanket implementationが定義されるように変更 →anyhow::Errorは該当しないのでコンパイルエラー

Slide 28

Slide 28 text

© 2024 Finatext Holdings Ltd. anyhow::Errorからblanket implがある型へ変換すればOK 27

Slide 29

Slide 29 text

© 2024 Finatext Holdings Ltd. Upstreamでさらに対応されてる模様 28 https://github.com/awslabs/aws-lambda-rust-runtime/pull/907

Slide 30

Slide 30 text

© 2024 Finatext Holdings Ltd. 実用Rustアプリケーション開発 29 https://zenn.dev/taiki45/books/pragmatic-rust-application-development

Slide 31

Slide 31 text

No content