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
try-catchからrunCatchingに_移行した話.pdf
Search
yuki anzai
August 24, 2019
Programming
6
3.2k
try-catchからrunCatchingに_移行した話.pdf
yuki anzai
August 24, 2019
Tweet
Share
More Decks by yuki anzai
See All by yuki anzai
5分でざっくり理解する Jetpack Compose
kuromame
0
220
Flux + Repositoryへリアーキテクチャ後にテストを書き始めて1ヶ月経った話
kuromame
4
350
Other Decks in Programming
See All in Programming
S3静的ホスティング+Next.js静的エクスポート で格安webアプリ構築
iharuoru
0
210
リアクティブシステムの変遷から理解するalien-signals / Learning alien-signals from the evolution of reactive systems
yamanoku
2
1.2k
RubyKaigiで手に入れた HHKB Studioのための HIDRawドライバ
iberianpig
0
1.1k
私の愛したLaravel 〜レールを超えたその先へ〜
kentaroutakeda
12
3.7k
snacks.nvim内のセットアップ不要なプラグインを紹介 / introduce_snacks_nvim
uhooi
0
370
Develop Faster With FrankenPHP
dunglas
2
2.9k
複雑なフォームと複雑な状態管理にどう向き合うか / #newt_techtalk vol. 15
izumin5210
4
3.7k
エンジニア未経験が最短で戦力になるためのTips
gokana
0
240
remix + cloudflare workers (DO) docker上でいい感じに開発する
yoshidatomoaki
0
120
PsySHから紐解くREPLの仕組み
muno92
PRO
1
530
Denoでフロントエンド開発 2025年春版 / Frontend Development with Deno (Spring 2025)
petamoriken
1
1.3k
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
740
Featured
See All Featured
How GitHub (no longer) Works
holman
314
140k
Speed Design
sergeychernyshev
28
870
Documentation Writing (for coders)
carmenintech
69
4.7k
Building Applications with DynamoDB
mza
94
6.3k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.6k
Unsuck your backbone
ammeep
670
57k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.2k
A designer walks into a library…
pauljervisheath
205
24k
Transcript
try-catchからrunCatchingに 移行した話 安齋祐紀 (@off2white)
自己紹介 安齋祐紀(あんざいゆうき) Twitter: @off2white 株式会社 ディー・エヌ・エー(DeNA) - 次世代タクシー配車サービス「 MOV」 -
Androidアプリ開発担当 - プロジェクト管理とコーディングの割合 = 50:50 (気持ちは) 最近の悩み いまだに運営さんが採択時に 人を間違えていなかったのか心配
None
背景 個人的エラーハンドリング の変遷
その1 むやみに例外を使わなくなった
ClassA ClassB ClassC Exception New ClassD 誰が Catch する? NewException
Not For Me Exception ?
ClassA ClassB ClassC sealed class New ClassD I Like sealed
class sealed class
ViewModel Repository Api Exception New DB ただし現実的にはこんな感じ sealed class Exception
その2 Crashlyticsの発達によって 細かくExceptionをCatchする必要が なくなった
蘇る悪夢 try { response = apiRequest.execute() dao.save(response.toEntity()) }
catch (e: IOException) { errorCode += “01” throw NetworkException(errorCode) } catch (e: SQLException) { errorCode += “03” throw GeneralException(errorCode) } catch (e: Throwable) { errorCode += “04” throw SystemException(errorCode) }
その3 Rx -> Coroutineへの移行
Rx では success と error 時の処理を 分けて記載できた repository.fetchData() .subscribeBy
( onNext = { livedata.postValue(it)}, onError = { Timber.e(it) } ) 実 行 系 正 常 系 異 常 系
もっと良いエラーハンドリングの書き方はないのか
runCatching (Kotlin 1.3)
runCatching { apiRequest.execute() } or apiRequest.execute()
.runCatching { dao.save(it.toEntity()) } こんな感じで書く
runCatchingは Resultクラスを返却する
成功結果と例外を カプセル化してくれる
val result = runCatching { apiRequest.execute() } if (result.isFailure)
{ Timber.e( result.exceptionOrNull() ) return } 処理結果を受け取って 返却してくれる
runCatching { apiRequest.execute() }.onSuccess { dao.save(it.toEntity()) }.onFailure { Timber.e(it) }
成功処理と失敗処理を 分けて記載できる 実 行 系 正 常 系 異 常 系
runCatching { apiRequest.execute() }.mapCatching { dao.save(it.toEntity()) }.onSucess { … }.onFailure
{ ... } map 時も Catch できる
runCatching { apiRequest.execute() }.recoverCatching { Response.default() } 例外処理のリカバリ処 理も綺麗にかける
これは是非使うべき!!!
結論 案外不評
try { res = apiClient.execute() dao.save(res.toEntity()) } catch (e: Exception)
{ Timber.e(e) } 正常パスと 例外処理で 別れている方が 好みの人もいる 正 常 パ ス 例 外 処 理 理由その1
val a: Int? = try { parseInt(input) } catch
(e: Exception) { null } Kotlin の try-catch は式 として書けるので それで十分説 理由その2
val a: Int? = try { parseInt(input) } catch
(e: Exception) { null } finally { ... } try-catch なら finally で 明示的に書ける (runCatching ではできない ) 理由その3
return runCatching { … } Result 型は return できない 理由その4
fun function() : Int { runCatching { "5".toInt() }.onSuccess {
return@function it }.onFailure { return@function 0 } // ここにreturnが必要 } a ‘return’ expression required in a function with a block body 理由その5
(;Ծ﹏Ծ)ぐぬぬ
runCatching { runFunction() }.onSuccess { dispatch(Action.Success) }.onFailure { dispatch(Action.Failure) }
現状は return しない ところで そっと使っている ActionCreator の dispatch とか ViewModel の LiveData.postValue とか
Resultクラスの KEEPでの議論が面白いので ぜひ読んでね!