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.3k
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
230
Flux + Repositoryへリアーキテクチャ後にテストを書き始めて1ヶ月経った話
kuromame
4
350
Other Decks in Programming
See All in Programming
Azure SRE Agentで運用は楽になるのか?
kkamegawa
0
970
サイトを作ったらNFCタグキーホルダーを爆速で作れ!
yuukis
0
740
Go言語での実装を通して学ぶLLMファインチューニングの仕組み / fukuokago22-llm-peft
monochromegane
0
110
ProxyによるWindow間RPC機構の構築
syumai
1
220
Laravel Boost 超入門
fire_arlo
2
170
Oracle Database Technology Night 92 Database Connection control FAN-AC
oracle4engineer
PRO
1
360
OSS開発者という働き方
andpad
5
1.6k
Portapad紹介プレゼンテーション
gotoumakakeru
1
130
Rancher と Terraform
fufuhu
2
170
The state patternの実践 個人開発で培ったpractice集
miyanokomiya
0
160
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
390
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
120
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
55
13k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
How STYLIGHT went responsive
nonsquared
100
5.8k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
51
5.6k
The Language of Interfaces
destraynor
160
25k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.8k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
61k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
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での議論が面白いので ぜひ読んでね!