アカウント名:
パスワード:
デバッガ「エミュレーション環境でチェックチェック~いけるねうん。OSバージョン別動作とかはまぁ無視して大丈夫でしょ。ヨシッ」配信担当「いけたみたいだね、俺は配信するだけだし。配信GO~~~~ ヨシッ!」
開発担当(ガラっ)「あのー、言い忘れてましたけど今回のバージョンから新しい機能いろいろ付けたんで動作チェックOS別に細かくお願いしますね~」
一同「。。。。。『原因は調査中です、まる』っと。よしっ!!」
本件のissue [github.com]より、
特定バージョン(v1.2.0)より前からのアップデートでデータが壊れ、今回のバージョンでアプリが落ちる。
実機でやってないからとか、OS別にやったからヨシなんてものではなく、真っ新な状態や旧バージョンからアップデート後の状態別にテストが必要と指摘できなければ、同じ穴の狢だろ。
> 特定バージョン(v1.2.0)より前からのアップデートでデータが壊れ、> 今回のバージョンでアプリが落ちる。
いや、そうとも限らないです。v1.2.0を経由していても駄目な場合があるという報告があります。(事実であれば)
あと、データが壊れる、というのもちょっと違うかと。利用規約を読んだ日時を記録するデータがあって、条件によっては、これが最小値(Ticks = 0 : グレゴリオ暦0001年1月1日0時0分0秒)のままになるみたい。(利用規約を読んだフラグだけ立って、日時が記録されていない状態)
最大のミスは、DateTime型への加減算で例外が発生しうることを認識していなかったことじゃないかと。JSTとUTCの変換時に9時間分の減算を行っていて、これが最小値より前の日時になると例外が発生してアプリが止まります。
指摘に「標準のタイムゾーン変換関数を使わないから」というものもありますけど、実はこれも間違い。標準の変換関数を使おうが、最小値より前になれば例外が発生します。
issueに書いてあるけど「例外が発生しうることを認識していなかった」ことが原因ではなく例外が発生する条件となる(最小値設定のコードが実行される)可能性が稀とつまり、デッドコードだと思っていたことが原因
すでにユーザーの端末にはMinValueが入力された状態で記録されてしまっているから、MinValueが入っていた時の迂回処理は必要。修正方法としてcatchを追加するのか、MinValueと同値かの条件分岐を入れるのかは好みの問題でしかないし、「加減算で例外が発生しうることを認識していなかった」の説明にはならない。例外に至るケースには至らないと考えていた場合、静的解析で警告が出ていたとしても、対処不要と判断される可能性のほうが高い。
それと、Javaの検査例外はそういった目的で使うものでは無い。実際、標準ライブラリの日付計算ではチェック例外が必要となってないし、場合によってはオーバーフローし、エラーにならずに望まない処理が行われる。
MinValueと同値かの条件分岐だとMinValue+8時間のときにやっぱり例外で落ちるのでダメですね。
妄想で語るべきでないし、そうして良いと思うならプログラミングはやめるべき。エラーとなった処理はJSTからUTCへの変換で、その処理は8時間減算であって加算ではない。 DateTimeの仕様 [microsoft.com]を読めば明らかが、DateTimeは0001年1月1日0時0分0秒~9999年23時59時59分を表現し、加減算はMinValue~MaxValueの範囲を超える場合に例外が発生する。MinValue(0001/1/1 00:00;00)に8時間を足した程度で、9999年は超えられず、つまり、MinValue-8時間なら例外は投げられるが、君の言う「MinValue+8時間のときにやっぱり例外で落ちる」は発生しない。
というか例外処理は
> 条件によっては、これが最小値(Ticks = 0 : グレゴリオ暦0001年1月1日0時0分0秒)のままになるみたい。
その条件というのが、特定バージョン(v1.2.0)より前からの(つまり利用規約同意日時を記録していなかった状態からの)アップデートということ。
v1.2.0を経由したらOKというのはどういう意図で書かれたのか理解できないが、v1.2.0より前→v1.2.0の段階では、プライバシーポリシー同意日時は追加されたとしても、利用規約同意日時の情報は追加されず、v1.2.0→v1.2.2~v1.4.0の段階で、最小値が記録され(v1.4.0にとって)壊れたデータとなり、v1.4.0で減算によりエラーとなる。
各バージョンでのデータごとにマイグレーションできるかのテストが用意できていれば、リリース前に気づくことができただろうけど、各OSごとのテストでは気づくことはできない。
そもそもJSTからUTCへタイムゾーンを変更するために9時間減らす処理をするのがおかしい。タイムゾーンを変更すべきでは?
その言い方は変だな。君は本当はこう言いたいんだろ?内部的にはJSTとみなしてそのまま処理すべきである、と。で、日時を表示する時だけ端末ロケールに合わせて加減すればいい。
まあUTCやエポックタイムの方が何かと都合がいいので、マイグレ時にJSTから変換しておきたいという心理はよく理解できる。ただ、一度誤って暗黙的なJSTで保存してしまった以上、無理に変換せず、そのまま取り扱うことも考慮すべきだったね。結果論だけど。
そもそもって話をするなら年月日を文字列として保存している時点で設計がおかしい普通にローカルデータベースにdata型で保存していれば何も問題は無かった筈。Xamarin側で勝手にunixタイムを捻じ曲げない限り、タイムゾーン関係なく処理できた筈。
境界値テストとかってそんなにレアな物なのでしょうか?MigrateDateTimeToEpoch相手に最小値食わせるテストしてれば防げたのにねぇ。
自分が作った設定ファイルだろうと外部入力値を信じたら駄目。未来の自分が作った値を食べさせられるパターンも有るし、エンドユーザー環境という魔窟は、初回アプリ起動時を元にした稼働日数が負になる事すら起きる(時計が狂ってるだけだが)。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
計算機科学者とは、壊れていないものを修理する人々のことである
yoshi! (スコア:0)
デバッガ「エミュレーション環境でチェックチェック~いけるねうん。OSバージョン別動作とかはまぁ無視して大丈夫でしょ。ヨシッ」
配信担当「いけたみたいだね、俺は配信するだけだし。配信GO~~~~ ヨシッ!」
開発担当(ガラっ)「あのー、言い忘れてましたけど今回のバージョンから新しい機能いろいろ付けたんで動作チェックOS別に細かくお願いしますね~」
一同「。。。。。『原因は調査中です、まる』っと。よしっ!!」
OSだけチェックすれば良いと思ってるの? (スコア:0)
本件のissue [github.com]より、
特定バージョン(v1.2.0)より前からのアップデートでデータが壊れ、
今回のバージョンでアプリが落ちる。
実機でやってないからとか、OS別にやったからヨシなんてものではなく、
真っ新な状態や旧バージョンからアップデート後の状態別にテストが必要と
指摘できなければ、同じ穴の狢だろ。
Re:OSだけチェックすれば良いと思ってるの? (スコア:1)
> 特定バージョン(v1.2.0)より前からのアップデートでデータが壊れ、
> 今回のバージョンでアプリが落ちる。
いや、そうとも限らないです。
v1.2.0を経由していても駄目な場合があるという報告があります。(事実であれば)
あと、データが壊れる、というのもちょっと違うかと。
利用規約を読んだ日時を記録するデータがあって、
条件によっては、これが最小値(Ticks = 0 : グレゴリオ暦0001年1月1日0時0分0秒)のままになるみたい。
(利用規約を読んだフラグだけ立って、日時が記録されていない状態)
最大のミスは、DateTime型への加減算で例外が発生しうることを認識していなかったことじゃないかと。
JSTとUTCの変換時に9時間分の減算を行っていて、
これが最小値より前の日時になると例外が発生してアプリが止まります。
指摘に「標準のタイムゾーン変換関数を使わないから」というものもありますけど、実はこれも間違い。
標準の変換関数を使おうが、最小値より前になれば例外が発生します。
Re: (スコア:0)
Visual Studio上で開発してればDateTime型変数を演算してる'+'なり'-'なりにカーソルをポイントするだけでArgumentOutOfRangeExceptionが出る可能性をポップアップで表示してくれるんだよなぁ
コンパイラがもうちょっと頑張れば、静的解析か何かでこれ誰もtry catchしてないんだけどいいんすか的な警告出せるんじゃなかろうか。
Re: (スコア:0)
issueに書いてあるけど「例外が発生しうることを認識していなかった」ことが原因ではなく
例外が発生する条件となる(最小値設定のコードが実行される)可能性が稀と
つまり、デッドコードだと思っていたことが原因
Re: (スコア:0)
Javaのチェック例外ならともかくC#じゃあそんなのはどんだけ気をつけていても漏れるんだから静的解析で警告出すのが正当だと思うよ。
Re: (スコア:0)
すでにユーザーの端末にはMinValueが入力された状態で記録されてしまっているから、MinValueが入っていた時の迂回処理は必要。
修正方法としてcatchを追加するのか、MinValueと同値かの条件分岐を入れるのかは好みの問題でしかないし、「加減算で例外が発生しうることを認識していなかった」の説明にはならない。
例外に至るケースには至らないと考えていた場合、静的解析で警告が出ていたとしても、対処不要と判断される可能性のほうが高い。
それと、Javaの検査例外はそういった目的で使うものでは無い。
実際、標準ライブラリの日付計算ではチェック例外が必要となってないし、場合によってはオーバーフローし、エラーにならずに望まない処理が行われる。
Re: (スコア:0)
というか例外処理は重いので、事前に条件分岐でチェックできるのならば例外処理を使うのは間違い。
プログラマーならば例外か事前チェックかの選択は明確で実は好みの問題ではないのです。 forループから抜けるのにカウンタがMaxになったときに例外投げたりしないでしょ。
Re: (スコア:0)
MinValueと同値かの条件分岐だとMinValue+8時間のときにやっぱり例外で落ちるのでダメですね。
妄想で語るべきでないし、そうして良いと思うならプログラミングはやめるべき。
エラーとなった処理はJSTからUTCへの変換で、その処理は8時間減算であって加算ではない。
DateTimeの仕様 [microsoft.com]を読めば明らかが、DateTimeは0001年1月1日0時0分0秒~9999年23時59時59分を表現し、加減算はMinValue~MaxValueの範囲を超える場合に例外が発生する。
MinValue(0001/1/1 00:00;00)に8時間を足した程度で、9999年は超えられず、
つまり、MinValue-8時間なら例外は投げられるが、君の言う「MinValue+8時間のときにやっぱり例外で落ちる」は発生しない。
というか例外処理は
Re: (スコア:0)
> 条件によっては、これが最小値(Ticks = 0 : グレゴリオ暦0001年1月1日0時0分0秒)のままになるみたい。
その条件というのが、特定バージョン(v1.2.0)より前からの(つまり利用規約同意日時を記録していなかった状態からの)アップデートということ。
v1.2.0を経由したらOKというのはどういう意図で書かれたのか理解できないが、
v1.2.0より前→v1.2.0の段階では、プライバシーポリシー同意日時は追加されたとしても、
利用規約同意日時の情報は追加されず、
v1.2.0→v1.2.2~v1.4.0の段階で、最小値が記録され(v1.4.0にとって)壊れたデータとなり、
v1.4.0で減算によりエラーとなる。
各バージョンでのデータごとにマイグレーションできるかのテストが用意できていれば、
リリース前に気づくことができただろうけど、各OSごとのテストでは気づくことはできない。
Re: (スコア:0)
そもそもJSTからUTCへタイムゾーンを変更するために9時間減らす処理をするのがおかしい。
タイムゾーンを変更すべきでは?
Re: (スコア:0)
その言い方は変だな。君は本当はこう言いたいんだろ?
内部的にはJSTとみなしてそのまま処理すべきである、と。
で、日時を表示する時だけ端末ロケールに合わせて加減すればいい。
まあUTCやエポックタイムの方が何かと都合がいいので、マイグレ時にJSTから変換しておきたいという心理はよく理解できる。
ただ、一度誤って暗黙的なJSTで保存してしまった以上、無理に変換せず、そのまま取り扱うことも考慮すべきだったね。結果論だけど。
Re: (スコア:0)
そもそもって話をするなら年月日を文字列として保存している時点で設計がおかしい
普通にローカルデータベースにdata型で保存していれば何も問題は無かった筈。
Xamarin側で勝手にunixタイムを捻じ曲げない限り、タイムゾーン関係なく処理できた筈。
Re: (スコア:0)
境界値テストとかってそんなにレアな物なのでしょうか?
MigrateDateTimeToEpoch相手に最小値食わせるテストしてれば防げたのにねぇ。
自分が作った設定ファイルだろうと外部入力値を信じたら駄目。
未来の自分が作った値を食べさせられるパターンも有るし、
エンドユーザー環境という魔窟は、初回アプリ起動時を元にした稼働日数が負になる事すら起きる(時計が狂ってるだけだが)。