失敗を捨てると、画面は嘘をつく:「○件登録しました」と出て 1 件も入っていなかったカレンダー、固まる文字認識、店名を積み忘れた通知
トレカダッシュ 開発の記録 / 2026年8月
iOS アプリ「トレカダッシュ」で、「失敗を、握りつぶしたせいで、嘘の成功を表示していた」という不具合が、続けて見つかりました。この記事は、そのうちの 3 つの記録です。
この記事は、2026 年 8 月 25 日の作業の記録から書いています。
1. カレンダーに 1 件も入っていないのに、「○件登録しました」
アプリには、抽選の締切を、iPhone のカレンダーに書き出す機能があります。ビルドの警告(result of 'try?' is unused)から、この処理を見直しました。try? は、Swift で、失敗を捨てる書き方です。この機能は、保存の処理を try? store.save(...) と try? store.commit() で呼び、失敗を捨てていました。
その結果、こうなっていました。
- 1 件もカレンダーに入っていないのに、「○件登録しました」と表示される。
- 「書き出し済み」の記録だけが残る。
- もう一度押すと、「新しく登録できる案件はありませんでした」と出て、永久に登録できなくなる。
直し方は、失敗を呼び出し元に返して、成功した件数だけ数えることでした。既定のカレンダーが無い端末は、先に検出して知らせます。案内の文も、理由ごとに分けました。それまでは、どんな失敗でも、「アクセスが許可されていません」と出していました。
2. 文字認識が失敗すると、画面が固まる
応募の画像から文字を読み取る機能(OCR)も、try? handler.perform([request]) で、失敗を捨てていました。文字認識が失敗すると、コールバック(終わったときの呼び出し)が、一度も呼ばれません。読み取り中の「ぐるぐる」が止まらず、画面を閉じる以外に、抜けられなくなっていました。
直し方は、失敗したときも、「認識し終わった(見つからなかった)」状態に戻すことです。
ビルドの警告、result of 'try?' is unused、は、握りつぶしの目印です。ビルドを流して、警告を定期的に見ます。
3. 通知に、店名が出ない:バッファに積み忘れた
別の話ですが、同じ形です。「通知に、店名がない」という報告が来ました。記事には、店名(sellerName)が、正しく入っています。それなのに、通知には出ていませんでした。
抽選と予約の通知は、いったんバッファ(一時置き場)に積んでから、まとめて送る設計です(サイレントな時間帯の保留と、送る回数の制限のため)。ところが、店名を、バッファに引き継いでいませんでした。送るときに、店名を探しても、もう情報が無く、カテゴリ(「ライヴポケット」)しか残っていません。
この症状は、前の報告の直し方が表に出した、という面もありました。「通知が、ライヴポケットという名前で来る」を直したとき、店名が分からない場合は、null を返すようにしました。この積み忘れが、「間違った店名」から、「店名なし」に、症状を変えて表に出たのです。
2 種類のバッファ(ジャンル別と、商品別)の両方に、同じ抜けがあったので、両方を直しました。すでに積まれていた 5 件は、記事から店名を補って、送るときに店名が出ることを確かめました。
同じ抜けは、8 月 17 日にも、別の項目(商品名)で起きていました。教訓は、バッファに積むときは、送るときに使う項目を、全部持たせることです。組み立て済みの文言をそのまま保存する、ほかの 2 つのバッファでは、この問題は起きません。
分かったこと
失敗を捨てると、画面は、嘘をつく。
- 失敗は、呼び出し元に返す。捨てると、成功の表示と、実際が食い違います。
- 失敗したときも、「終わった」状態に戻す。コールバックが呼ばれないと、画面が固まります。
- 成功の記録は、成功したときだけ。失敗しても残ると、再試行ができなくなります。
- ビルドの警告を読む。
try?の警告は、握りつぶしの目印です。 - バッファには、送るときに使う項目を、全部積む。後から、別の項目で、同じ抜けが出ます。
この話に出てくるもの
- トレカダッシュ — トレカの抽選・予約・先着の情報を集める iPhone アプリ
- iOS アプリが固まって強制終了される — アプリの別の不具合
- 本物の抽選を、静かに捨てていた 4 つの実例 — 静かに失敗した別の実例
ほかの記録
- 候補は見つかっていたのに、答えを読む所で毎回落ちていた:200 トークンで切れた URL と、ハイフンで 400 になる検索 — 公式の告知ページを選ぶ AI の返事が 200 トークンで途中で切れて毎回失敗していた。直しても 0 件だったのは、店の告知が個別の商品名を書かないため、AI が指示に忠実に拒否していたから。楽天の検索は、ハイフンの位置で 400 になった。
- 「iCloud が新しければ取り込む」の関数が、何も比べていなかった:応募の記録が 20 件から 1 件になりうる — iCloud 同期の関数は、名前に反して新しいかを見ず、変更があると丸ごと置き換えていた。新しい端末の空の状態で保存すると、別の端末の 20 件が 1 件に上書きされうる。更新時刻を比べ、空では上書きしないようにした。
- 「後から掃除するから大丈夫」が、入口の不具合を隠していた:商品が毎日 400 件そっくり作り直されていた — カタログからの商品登録が名前の完全一致でしか探さず、括弧・空白・全角の違いで毎日そっくりな商品を作り直し、この日だけで 437 件(410 件は記事なし)。統合の掃除が後から片付けていたため気づけなかった。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。