# FONTELIER_IOS_DEV-516 /api/v1/receipt/check 5xx エラー調査依頼 ## URL <https://morisawa.backlog.jp/view/FONTELIER_IOS_DEV-516> ## 調査 ### Kuwae通話Memo <https://morisawa.backlog.jp/view/FONTELIER_IOS_DEV-516>の ``` text 松浪信博 2019/12/20 16:03:32 ログを確認してみましたが現状2パターン存在する形です 1.30秒経過によるタイムアウト タイムアウトしている際はレシート検証でAppleからのレスポンスを待っている間に30秒経過してしまっています。 2.Appleからのレスポンス内容が想定外のパターン こちらはレスポンス内容が分からないため、推測になりますが以下のパターンが起こりえるようです ・Apple のサーバに繋がらない ・Apple が返してきた結果が壊れていた(HTTP にすらなっていない) ・Apple が返してきた結果が 200 系以外だった ・Apple が返してきたデータが有効な JSON になっていない ・Apple が返してきたデータが有効な JSON になっているけど、必要な項目が入っていない 2のパターンは一度レスポンス内容をログ出力する処理を追加してみないと分からないですが・・・ それぞれ発生したらアプリ側からリトライ処理とかが必要になったりしそうです (現状チェック時のみ発生していますが購入時でも起こるかもしれません) ``` ### Kuwaeさん曰く 1と2のパターンの修正が必要。 1の場合は、30秒経過するとトライするように。 2の場合、StatusCodeは000以外だとおかしいから、それを確認すれば良さそう。 ### 問題箇所のコード ## 改修案 ### 1.30秒経過によるタイムアウト ``` swift class InAppPurchaseFacade { func verifyExistingReceipt() -> Single<ReceiptVerificationResponseParameters> { let receiptData = SwiftyStoreKit.localReceiptData?.base64EncodedString() ?? "" let request = ExistingReceiptVerificationRequest(receiptData: receiptData) return apiAccess.callWithInternetConnectionCheck(request) } } struct ExistingReceiptVerificationRequest: WebApiRequest { typealias RequestParameterType = ReceiptVerificationRequestParameters typealias ResponseParameterType = ReceiptVerificationResponseParameters var webApiRequestParameters: ReceiptVerificationRequestParameters init(receiptData: String) { webApiRequestParameters = ReceiptVerificationRequestParameters(receipt: receiptData) } var path: String { WebApiConstants.verifyExistingReceipt.path } var method: HTTPMethod { .post } var timeout: TimeInterval { WebApiConstants.existingReceiptVerificationTimeout } } ``` `ExistingReceiptVerificationRequest`の `var timeout: TimeInterval` を30秒から60秒?90秒?に変更 ### 2.Appleからのレスポンス内容が想定外のパターン ``` swift class InAppPurchaseFacade { func verifyExistingReceipt() -> Single<ReceiptVerificationResponseParameters> { let receiptData = SwiftyStoreKit.localReceiptData?.base64EncodedString() ?? "" let request = ExistingReceiptVerificationRequest(receiptData: receiptData) return apiAccess.callWithInternetConnectionCheck(request) } } struct ReceiptVerificationResponseParameters: WebApiResponseParameters { let responseCode: String let errorMessage: String? let errorList: [WebApiResponseError]? let res: [ReceiptVerificationMainResponse]? } ``` verifyExistingReceipt()の改修で 2の場合は ReceiptVerificationResponseParametersのresponseCodeが000かどうかを確認する。