⚠️

iOS アプリのエラー情報から定義情報を逆引きするサイトを作った

2022/10/17に公開

はじめに

アプリ開発において Crashlytics などで非致命的な例外を収集することがあると思います
その際に送られてくるレポートは以下のような情報でヒトが見た際は雰囲気はわかりますが、それをハンドリングしようとすると、ひとクセあります

Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x6000006380c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_NSURLErrorNWPathKey=unsatisfied (No network route), _kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDownloadTask <A26E4B41-E3AF-4603-9646-D2E27E1D65D3>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDownloadTask <A26E4B41-E3AF-4603-9646-D2E27E1D65D3>.<1>"
), NSLocalizedDescription=The Internet connection appears to be offline., NSErrorFailingURLStringKey=https://httpbin.org/get, NSErrorFailingURLKey=https://httpbin.org/get, _kCFStreamErrorDomainKey=1}

愚直に判定するならこうなりますが、マジックナンバーもあり判定文も長く Swift らしくありません

switch error {
case let e as NSError where e.domain == NSURLErrorDomain && e.code == -1009:
    ...
}

そこで本来はこのように書きたいところですが、

switch error {
case URLError.notConnectedToInternet:
    ...
}

NSURLErrorDomain から URLError は推測できても、 code は URLError の定義にジャンプしても対応している直値がわかりません
またドキュメントを参照しても、同様に code の実体について記載がありません

Objective-C の頃は定義にジャンプするとこのように対応する宣言と値が一覧で見れたので、困ることはなかったのですが、

/*!
    @enum NSURL-related Error Codes
    @abstract Constants used by NSError to indicate errors in the NSURL domain
*/
NS_ERROR_ENUM(NSURLErrorDomain)
{
    NSURLErrorUnknown = 			-1,
    NSURLErrorCancelled = 			-999,
    NSURLErrorBadURL = 				-1000,
    NSURLErrorTimedOut = 			-1001,
    NSURLErrorUnsupportedURL = 			-1002,
    NSURLErrorCannotFindHost = 			-1003,
    NSURLErrorCannotConnectToHost = 		-1004,
    NSURLErrorNetworkConnectionLost = 		-1005,
    NSURLErrorDNSLookupFailed = 		-1006,
    NSURLErrorHTTPTooManyRedirects = 		-1007,
    NSURLErrorResourceUnavailable = 		-1008,
    NSURLErrorNotConnectedToInternet = 		-1009,  // ←
    NSURLErrorRedirectToNonExistentLocation = 	-1010,
    ...

Swift になってからは、送られてくるエラーレポートの対応でマッチする定義を探す際にちょくちょく困っていました
ただ困ってはいるものの自分の探し方が悪いと考え放置していましたが、この前同じく困っている方を見かけて、せっかくならと逆引きできるサイトを作ってみました

Cococa Errors

https://cocoa-errors.onrender.com

技術スタックとしては Typescript + React + Mantine を用いて Static Site 形式で render.com にホスティングしています
このあたりは初めての領域かつ見様見真似で作ったのであまり解説できることはありません 💦

絞り込み機能はひとまず単純にエラーレポートのドメイン名で絞り込んだ後はブラウザ検索や目視で目的の code を見つけるものとして、ドメインからの絞り込みのみになっています


エラー情報データに関しても特に複雑なことはしておらず SDK 内のヘッダ定義をなめて NS_ERROR_ENUM に該当する部分を拾って抽出しています
こちらは普段書き慣れた Swift で作成しました

リポジトリはこちらで公開しています

https://github.com/swiftty/cocoa-errors

おわりに

前々から欲しいと思っていた機能をこの機会に作ることができて良かったです
Typescript は今まで軽く触れる程度だったので調べることに大部分の時間を費やしました 💦(環境構築、 UI ライブラリ選定、ホスティング方法等、...)
が、ある程度形が組み上がってくるとプレビューからデプロイまでどれもシンプルで思っていたほどのハードルが無かったのも良かったです

Discussion