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
iOS アプリエラー監視の設計とその効果
Search
Kuniwak
PRO
November 20, 2017
Programming
9.2k
33
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS アプリエラー監視の設計とその効果
Kuniwak
PRO
November 20, 2017
More Decks by Kuniwak
See All by Kuniwak
Codex を使った障害対応机上演習の実際
orgachem
PRO
0
380
AIベース静的検査器の偽陽性率を抑える工夫3選
orgachem
PRO
8
3.2k
仕様漏れ実装漏れをなくすトレーサビリティAI基盤のご紹介
orgachem
PRO
16
12k
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
40
24k
DeNA での思い出 / Memories at DeNA
orgachem
PRO
8
3.8k
それ CLI フレームワークがなくてもできるよ / Building CLI Tools Without Frameworks
orgachem
PRO
18
4.9k
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
4
830
テストケースの名前はどうつけるべきか?
orgachem
PRO
2
1.1k
欠陥を早期に発見するための Software Engineer in Test とその重要性 / What is Software Engineer in Test and How they works
orgachem
PRO
22
5.2k
Other Decks in Programming
See All in Programming
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
2
1.2k
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
1k
contenteditable と日本語入力に向き合う
colorful12
0
230
最近”作らせてる” ローカルAIアプリの話
akit37
0
500
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
120
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
220
動画プレイヤーはなぜカクつくのか 〜Flutterのレンダリングとネイティブの境界を解剖する〜
naruogram
0
170
Spec-Driven Development - Why Vaadin Is the Perfect Fit
simas
PRO
0
150
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
390
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
190
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.9k
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
920
How to Talk to Developers About Accessibility
jct
2
590
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
310
Reality Check: Gamification 10 Years Later
codingconduct
0
2.4k
GraphQLとの向き合い方2022年版
quramy
50
15k
Ruling the World: When Life Gets Gamed
codingconduct
0
420
Building Applications with DynamoDB
mza
96
7.3k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
280
Transcript
J04ΞϓϦΤϥʔࢹͷ ઃܭͱͦͷޮՌ
"CPVUNF
,VOJXBL גࣜձࣾ%JWFSTFͷJ04ςοΫϦʔυɻ ͱ͋ΔΞϓϦͷϦχϡʔΞϧϓϩδΣΫτʹ ్த͔ΒՃΘͬͨͷͷɺςετࠔͳઃܭΛ ͷͨΓʹͨͨ͠ΊɺཪϦχϡʔΞϧΛ։࢝ɻ ࠷ऴతʹςετΛಋೖ͠ɺ։ൃΛഒʹͨ͠ɻ झຯ5%%ɻ
Τϥʔࢹͱ
w ΞϓϦͰൃੜͨ͠ΤϥʔΛαʔόʹૹΔͳͲͯ͠ ΤϥʔͷൃੜͳͲΛࢹ͢Δٕज़ w ྫ͑ɺΞϓϦ͕Ϋϥογϡͨ͠ΒϨϙʔτΛ ඈ͢ΫϥογϡϨϙʔτ͜ͷҰछ w ΫϥογϡϨϙʔτղੳαʔϏεͰ $SBTIMZUJDT͕༗໊
Τϥʔͷൃੜ66 Τϥʔͷ*% ΤϥʔͷΧςΰϦ Τϥʔൃੜͷ࣌ؒతਪҠ Τϥʔൃੜ࣌ͷσόΠε Τϥʔൃੜ࣌ͷ04
w ࣮ɺଟ͘ͷΫϥογϡϨϙʔταʔϏε ΫϥογϡҎ֎ͷΤϥʔࢹͰ͖Δ w ྫ͑ɺ8FC"1*ݺͼग़࣌͠ͷΤϥʔɺ ෦ঢ়ଶͷෆ߹ͳͲͷΤϥʔࢹͰ͖Δ ૹ৴ͷํޙͰհ͠·͢
Τϥʔࢹͷಛੑ
w ΤϥʔࢹͷಛੑҎԼͷͭɿ w ඇৗʹൣͳόάΛݕͰ͖Δ w Τϯόά͔Βൃݟ·Ͱͷ͕͍࣌ؒ
ਤղ
όάΛݟ͚ͭΔͨΊͷखஈ ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ
όά9Λݟ͚ͭΒΕΔॴ όά9 ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ
όά9 ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ ্ͷํͰࢭ·Δͱ
ݪҼڀ໌ͷ͕͍࣌ؒ όά: ಛघͳΤϥʔԼͷํͰ ͔͠ݟ͚ͭΒΕͳ͍
ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ Τϥʔࢹಛघͳ ΤϥʔΛݟ͚ͭΒΕΔ
΄΅࠷ޙͷࡆ όά: ͔͠͠ɺ্ͷΑΓ Τϯόά͔Βൃݟ·Ͱͷ ͕࣌ؒͱ͍ͯ
ΤϥʔࢹͰݟ͚ͭΔ͖ Τϥʔͱ
ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ ༧ޠλΠϙ ม໊λΠϙ
ϓϩύςΟ໊ λΠϙ ذߟྀ࿙Ε ίϯϙʔωϯτ ༷ͷෆ߹ ༷ͷޡղ ಛघͳڥͰ͔͠ ࠶ݱ͠ͳ͍Τϥʔ ҋ ཧͷόάݕͷ࢟
ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ ༧ޠλΠϙ ม໊λΠϙ
ϓϩύςΟ໊ λΠϙ ذߟྀ࿙Ε ίϯϙʔωϯτ ༷ͷෆ߹ ༷ͷޡղ ಛघͳڥͰ͔͠ ࠶ݱ͠ͳ͍Τϥʔ ҋ όά͕Լͷ·Ͱ ಥ͖ൈ͚ͯ͠·͏ͷͰ ݪҼڀ໌ʹ͕͔͔࣌ؒΔ μϝͳόάݕͷ࢟
ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ ༧ޠλΠϙ ม໊λΠϙ
ϓϩύςΟ໊ λΠϙ ذߟྀ࿙Ε ίϯϙʔωϯτ ༷ͷෆ߹ ༷ͷޡղ ಛघͳڥͰ͔͠ ࠶ݱ͠ͳ͍Τϥʔ ҋ ཧͷόάݕͷ࢟
ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔࢹ Ϣʔβʔ͔Βͷ͓͍߹Θͤ ༧ޠλΠϙ ม໊λΠϙ
ϓϩύςΟ໊ λΠϙ ذߟྀ࿙Ε ίϯϙʔωϯτ ༷ͷෆ߹ ༷ͷޡղ ಛघͳڥͰ͔͠ ࠶ݱ͠ͳ͍Τϥʔ ҋ ΤϥʔࢹͰݕ͖͢ Τϥʔ͜ͷ͋ͨΓ
͜͜·Ͱͷ·ͱΊ w ΤϥʔࢹಛघͳόάΛ ݕ͢ΔͨΊͷखஈ w ͳ͓ɺͦͷલͷखஈͰόάΛ ݟ͚ͭΒΕΔͳΒͦͷํ͕ ݪҼڀ໌Λ͘Ͱ͖Δ
Τϥʔࢹͷ࣮ํ๏
ΤϥʔࢹαʔϏεͷ"1*ΛѲ͢Δ ΤϥʔϨϙʔλʔΛΧελϚΠζ͢Δ ΤϥʔϨϙʔλʔΛΈࠐΉ
ΤϥʔࢹαʔϏεͷ "1*ΛѲ͢Δ
Crashlytics.sharedInstance().recordError(error) $SBTIMZUJDTʹΤϥʔΛૹ৴͢Δίʔυ &SSPSͰͳ͘/4&SSPSͳͷͰҙ
ΤϥʔϨϙʔλʔΛ ΧελϚΠζ͢Δ
/4&SSPSʹม͢Δͷ ໘ͳͷͰɺ4XJGUͷ&SSPSΛ /4&SSPS͍͍ײ͡ʹ มͯ͘͠ΕΔϥούʔΛॻ͘ $SBTIMZUJDTͷ߹
class CrashlyticsErrorReporter { private let crashlytics = Crashlytics.sharedInstance() func report(error:
Error, from reporter: Any) { #if DEBUG let prefix = "DEBUG " #else let prefix = "" #endif let detailedError = NSError( domain: "\(prefix)\(type(of: reporter))", code: CrashlyticsErrorTracker.getNSErrorCode(bySwiftError: error), userInfo: [ NSLocalizedDescriptionKey: "\(error)", ] ) self.crashlytics.recordError(detailedError) } private static func getNSErrorCode(bySwiftError error: Error) -> Int { let bridgedError = error as NSError return bridgedError.code } } %(ϏϧυΛ۠ผͰ͖ΔΑ͏ʹ͓ͯ͘͠ͱ ຊ൪ڥͱ։ൃڥΛ۠ผ͘͢͠ͳΔ ΤϥʔϨϙʔλʔʹͲͷΑ͏ʹ ूܭ͞ΕΔ͔Λҙࣝ͢Δ ྫ͑ɺ$SBTIMZUJDT/4&SSPSͷ EPNBJOͱDPEFͷͰΤϥʔΛ άϧʔϐϯά͢ΔͷͰɺͦΕͧΕ Τϥʔ*%ͱൃੜݩΛࢦఆ͢Δͱ ៉ྷʹΤϥʔ͕·ͱ·Δ ΤϥʔͷશจάϧʔϐϯάʹΘͳ͍Α͏ʹ͢Δ ʢϢʔβʔ*%ͱ͔͕ೖΔͱݸผͷΤϥʔʹͳͬͯ ૯ΛѲͰ͖ͳ͘ͳΔͷͰʣ $SBTIMZUJDT༻ͷΤϥʔϨϙʔλʔΛ࡞ SFQPSUؔΛݺͿͱΤϥʔϨϙʔτ͕ ૹ৴͞ΕΔΑ͏ʹ࣮͍ͯ͠Δ ΤϥʔͱҰॹʹൃੜݩ͕ Θ͔ΔΑ͏ʹ͓ͯ͘͠ͱ ݪҼͷݟ͕͖ͭ͘͢ͳΔ
ΤϥʔϨϙʔλʔΛ ΈࠐΉ
Α͘ΈΔΈࠐΈํ๏
class UserApiRepository: UserRepositoryProtocol { private let api: GitHubApiClientProtocol func get(by
id: GitHubUser.Id) -> Promise<GitHubUser> { return self.api .fetch( endpoint: GitHubApiEndpoint(path: "/user/" + id.text), headers: [:], parameters: [] ) .then { data -> GitHubUser in let response: GitHubUserResponse = try unbox(data: data) return response.user } .catch { error in ErrorReporter.shared.report( error: error, reporter: self ) } } } Τϥʔ͕ฦ͖ͬͯͨΒ ΤϥʔϨϙʔτΛૹ৴ ʢͭ·Γϋʔυίʔυʣ "1*ݺͼग़͠ͷίʔυ
w ͔͠͠ϋʔυίʔυʹ͕ଟ͍ɿ w "1*ͷݺͼग़͠ʹؔͷͳ͍ίʔυ͕ೖΔͨΊ ୯Ұݪଇʹҧ͢Δ w ୯ମςετͰΤϥʔϨϙʔτ͕ૹΒΕͯ͠·͏ w ςετ͚࣌ͩ༗ޮͳϑϥάΛՃͯ͠ ΤϥʔϨϙʔτΛૹ৴͠ͳ͍Α͏ʹ
Ͱ͖ͳ͘ͳ͍͕Γͨ͘ͳ͍
ͦ͜Ͱ0CTFSWFSύλʔϯ
w 0CTFSWFSύλʔϯͰɺࢹऀ͕ࢹରͷ ঢ়ଶมԽΛͯ͠ಈ࡞͢Δ w ΤϥʔϨϙʔτʹԠ༻͢Δͱɿ w ࢹऀΤϥʔϨϙʔλʔ w ࢹରΤϥʔ͕ൃੜ͠͏ΔΦϒδΣΫτ w
0CTFSWFSύλʔϯΛ͑ϋʔυίʔυͷ ΛղফͰ͖Δ
Τϥʔͷൃੜݯ Τϥʔ͕ൃੜ͠·ͨ͠ ΤϥʔϨϙʔλʔ ࢹ
Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ࢹ Τϥʔ͕ى͖ͨͷͰ ΤϥʔϨϙʔτΛ ૹ৴͠·͢
Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ΤϥʔϨϙʔτૹ৴ ͷ Τϥʔ͕ى͜Γ͏Δ ॲཧͷ
Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ςετͷͱ͖ ΤϥʔϨϙʔλʔ ΛऔΓ͚ͳ͍
w ͨͩ͠ɺ0CTFSWFSύλʔϯΛ͑Δॴ ݶΒΕ͍ͯΔ w ࢹର͕ࢹՄೳͳΠϯλʔϑΣʔεΛ උ͍͑ͯͳ͍ͱ͍͚ͳ͍ͨΊ w .7 ΞʔΩςΫνϟͳΒɺ.PEFMࢹՄೳͳ ΠϯλʔϑΣʔεΛ͍࣋ͬͯΔͣͳͷͰɺ.PEFMʹ
ΤϥʔϨϙʔλʔΛΈࠐΈ͍ͣ͢ w 'MVYΞʔΩςΫνϟͷ߹4UPSF͕ࢹՄೳͳ ΠϯλʔϑΣʔεΛ͍࣋ͬͯΔͣ
.PEFM 7JFX &SSPS3FQPSUFS ࢹ ࢹ Τϥʔ͕ൃੜ͠·ͨ͠
.PEFM 7JFX &SSPS3FQPSUFS ࢹ ࢹ ΤϥʔΛදࣔ͠·͢ ΤϥʔϨϙʔτΛ ૹ৴͠·͢
func fetch() { switch self.currentState { case .fetching: return case
.fetched: self.stateMachine.transit(to: .fetching) self.repository.get(by: self.id) .then { user in self.stateMachine.transit(to: .fetched( result: .success(user) )) } .catch { error in self.stateMachine.transit(to: .fetched( result: .failure(.unspecified(debugInfo: "\(error) )) } } } ͜ͷ.PEFM"1*ݺͼग़͕͠Τϥʔʹ ͳͬͨΒΤϥʔঢ়ଶมԽ͢Δ ͦͷͨΊɺΤϥʔϨϙʔλʔ͔Βࢹ͍͢͠ .PEFMͷ"1*ݺͼग़͠ͷίʔυ ͜ͷΑ͏ͳ.PEFMͷઃܭͷৄࡉIUUQTHPPHM1G'+-Λࢀর͍ͯͩ͘͠͞
class UserModelErrorReporter { private let model: UserModelProtocol private let errorReporter:
ErrorReporterProtocol private let disposeBag = RxSwift.DisposeBag() init( observing model: UserModelProtocol, reportingBy errorReporter: ErrorReporterProtocol ) { self.model = model self.errorReporter = errorReporter self.model.didChange .subscribe(onNext: { [weak self] (state: UserModelState) in guard let `self` = self else { return } switch state { case let .fetched(result: .failure(error)): self.errorReporter.report(error: error, reporter: self) default: return } }) .disposed(by: disposeBag) } } .PEFM͕Τϥʔঢ়ଶʹͳͬͨΒ ΤϥʔϨϙʔτΛૹ৴ .PEFMͷঢ়ଶભҠΛࢹ .PEFMΛࢹ͢ΔΤϥʔϨϙʔλʔΛ࡞
͜͜·Ͱͷ·ͱΊ w Τϥʔࢹͷ࣮ํ๏ʹ 0CTFSWFSύλʔϯ͕ద͍ͯ͠Δ w .PEFM4UPSFΛࢹ͢ΔͱΑ͍
Τϥʔࢹͷίπ
ΤϥʔࢹΛ։࢝͢Δͱ ࠔౕ͕ͬͨͪΐͪ͘ΐ͘ग़ͯ͘Δ
Fatal Exception: SomethingError *** nil ใྔ͕΄ͱΜͲͳ͍ʂ
ΤϥʔʹͳΔ͘ ΫϦςΟΧϧͳใΛ٧ΊΑ͏
func example(input: String) -> String? { guard validate1(input) else {
return nil } guard validate2(input) else { return nil } guard validate3(input) else { return nil } return "OK! Hello \(input)" } ݪҼڀ໌Λ͘͢Δѱ͍ྫ ࣦഊͨ͠ݪҼ͕۠ผͰ͖ͳ͍
enum ExampleError: Error { case validate1(debugInfo: String) case validate2(debugInfo: String)
case validate3(debugInfo: String) } ͦ͏͍͏࣌FOVNͰΤϥʔΛ۠ผͰ͖ΔΑ͏ʹ͢Δ
func example(input: String) -> Result<String> { guard validate1(input) else {
return .failure(.validate1(debugInfo: input)) } guard validate2(input) else { return .failure(.validate2(debugInfo: input)) } guard validate3(input) else { return .failure(.validate3(debugInfo: input)) } return .success("OK! Hello \(input)") } ΤϥʔΛ۠ผ͍͢͠Α͍ྫ ࣦഊͨ͠ݪҼ͕۠ผͰ͖Δ ࣦഊͨ͠ࡍͷೖྗೖखͰ͖Δ
Τϥʔࢹͷ݁Ռ
w ϢʔβʔͷखݩͰൃੜ͍ͯ͠Δόάͷछྨ نΛѲͰ͖ΔΑ͏ʹͳͬͨ w छྨن͕ѲͰ͖ΔΑ͏ʹͳΔͱɺόάमਖ਼ͷ τϦΞʔδΛΓ͘͢ͳΔ w ՝ۚܥ࠷༏ઌͱ͔ɺΤϥʔͷଟ͍ͷ ͔ΒରॲͳͲ
w ϢʔβʔͷखݩͰ༧֎ͷΤϥʔ͕ى͍ͬͯͨ͜ w ςελʔʹΑΔಈ࡞֬ೝͱڥ͕ ҟͳ͍ͬͯͨͨΊɺൃݟͰ͖ͳ͔ͬͨΑ͏ͩ w ໘ന͍͜ͱʹɺ"QQMFͷϨϏϡʔΞ͕ૺ۰ͨ͠ όάͷݪҼڀ໌ʹཱͬͨ w 4BOECPYͷϨγʔτ͡Όͳ͍ͱ࠶ݱ͠ͳ͍
όάͩͬͨ
w خ͍͠෭࡞༻ͱͯ͠ɺςελʔͷૺ۰ͨ͠όάͷ ৄࡉ͕ೖखͰ͖ΔΑ͏ʹͳͬͨ w ςελʔͷಈ࡞֬ೝதʹΤϥʔϨϙʔτ͕ ඈΜͰ͘ΔͨΊʢ%(ϏϧυͳͷͰ͙͢Θ͔Δʣ w σόοά͕͍͢͝ḿΓ·͢
·ͱΊ w ΤϥʔࢹʹΑΓɺςελʔʹΑΔಈ࡞֬ೝͰ ݟ͚ͭΒΕͳ͔ͬͨΤϥʔΛൃݟͰ͖ΔΑ͏ʹ ͳͬͨ w ઃܭͷίπҎԼͷͭɿ w 0CTFSWFSύλʔϯΛ͏ w
ͳΔ͘ΤϥʔใΛΘ͔Γ͘͢͢Δ
એ w %JWFSTFͰ৽نࣄۀͷJ04։ൃνʔϜͷ νʔϜϦʔμʔΛืू͍ͯ͠·͢ʂ w தͷαʔϏεΛࣗͷྗͰಋ͍ͯΈ͍ͨͱ ࢥ͏ํʹɺͥͻ͖ͯ΄͍͠ͱࢥ͍ͬͯ·͢ʂ w ͝ڵຯ͕͋Γ·ͨ͠ΒɺҰॹʹϥϯνʹ ߦ͖·ͤΜ͔ʁ