Android/Chromeで絵文字セレクターがメッセージエディタをクラッシュさせる

この問題は数ヶ月前から存在しており、Meta 社内の最新 Android/Chrome デバイスでも再現可能です。実際、1 月頃以来、数ヶ月にわたり発生しています。

メッセージエディタが、提案された絵文字を選択した際に、ときどき「クラッシュ」しているようです。

再現手順:

  1. トピックに返信を投稿し、いくつかのテキストを追加します。
  2. 「:+1」と入力して親指を立てる絵文字を追加し始め、提案された絵文字 :+1: をタップします。

発生する現象:

エディタが何らかの原因でクラッシュするか、再描画されます。通常、入力したテキストの一部が失われます。

100% 再現するわけではありませんが、数分間の操作で簡単に問題を発生させることができます。

「いいね!」 2

お使いの Android または Chrome の正確なバージョンは何ですか?

再現可能です。スタックトレースは以下の通りです:

_application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.js:16386 Uncaught TypeError: Cannot read property '0' of null
    at HTMLLIElement.<anonymous> (application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1)
    at HTMLLIElement.dispatch (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
    at HTMLLIElement.d.handle (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
(anonymous) @ application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1
dispatch @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1
d.handle @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1

問題はこの行です:

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/autocomplete.js#L308

エラーは、selectedOption が 0(単一の提案、つまり最初のもの)である一方で、autocompleteOptions が何らかの理由で null になっているために発生しています。

現在、その原因を調査中です。

現時点ではなぜそうなっているのか確信が持てません。当初は @Osama によるこの PR を疑っていました:

しかし、いくつかのブレークポイントを追加しても、autocompleteOptions を変更して null に設定している「誰」を特定できませんでした。

autocompleteOptions が 2 つ上のスコープを持つ親クロージャ由来であることも非常に奇妙で、コードの追跡やデバッグを少し困難にしています。

「いいね!」 8

Android 11 / Chrome 89(最新バージョン)

「いいね!」 1

@ljpp / @falco このバグを再現できますか?絵文字を挿入するさまざまなパターンを試しましたが、一度も再現できませんでした。もし再現できる場合は、正確な手順を共有していただけますか?ありがとうございます!

「いいね!」 1

はい、Chrome Android でもまだクラッシュします。再現させるには非常に具体的なため、手順を100%厳密に守る必要があります。

「いいね!」 1

試しましたが、簡単には再現できませんでした。ただし、夏の間、実際に投稿を入力している最中に偶然、数回この現象を目撃したことは確かです。

編集:コミュニティに、より包括的なテストカバレッジを提供できるか尋ねてみます。

編集2:ああ、はい、今自分でも再現できました。コミュニティが現在テスト中で、一般ユーザーからも同様の現象がいくつか報告されているようです。

「いいね!」 1

うっかり再現してしまいましたので、まだオープンな状態です。

この件は引き続きリストに残っていますが、再現とデバッグが極めて困難なため、対応に苦慮しています。

あまりにも難易度が高いため、pr-welcome を付けることはできません。いずれ再検討する予定ですが、今回は6ヶ月の期限を設けます。

この問題は現在も発生していますか?

はい、発生しています。私自身は15分間激しく操作を試みても再現できず、コミュニティにサポートを依頼しました。複数のユーザーが再現に成功し、そのうちの1人はスクリーンショットで証明しました。症状は変わっていません。セレクターで親指を立てる絵文字をタップすると、キーボードが折りたたまれ、エディタ内の入力された一部のコンテンツが失われます。

以前は非常に簡単に再現できていたのですが、現在はうまく再現できません。そのため、この問題は存在するものの、100%再現するものではありません。引き続き操作を試み、これを引き起こす特定のUIステップがあるかどうかを特定していきます。

「いいね!」 1

再現できる方がいれば、try.discourse.org でも再現できるか確認してもらえますか?

試さなくても再現できました。

Firefox 94.1.1 (ビルド #2015842491)

Chrome 95.0.4638.74

「いいね!」 2

ネイティブではないプラットフォームの絵文字セレクターが本当のバグだと思います。 :wink: 簡単な回避策は、お使いのOSのネイティブ絵文字ピッカーを使用することですか?

通常、回避策はあります。ただし、常にそうとは限りません。たとえば、Discourse でカスタム絵文字が使用されている場合があります。

いずれにしても、ページをリロードして記述されたコンテンツを失うのは、修正すべき悪い動作です。

はい、本日再度確認したところ、スマートフォンの仮想キーボードをGboardに切り替えた後に再現させることができました。Gboardは、キーを1回押しただけでkeydownkeyupイベントを2回発生させることがあります。もし、絵文字をオートコンプリートから選択する直前に押した最後のキーでこれが発生すると、クラッシュします。

Gboardがこれらのイベントを2回発生させる原因は不明ですが、入力内容やGboardの設定に依存するようです。

この二重イベントは、オートコンプリートライブラリの設計上の理由でクラッシュを引き起こします。ライブラリはkeydownkeyupの両方のイベントをリッスンし、keydownでオートコンプリートの候補をクリアし、keyupで新しいオートコンプリート用語に基づいて新しい候補を提供します。

しかし、用語が以前の候補から変更されていない場合にライブラリが重複作業を行うのを防ぐための小さなガード/最適化があり、ここで問題が発生します。最初のkeydownkeyupイベントのペアは、予想どおり古い候補をクリアして新しい候補を提供しますが、2番目の誤ったペアはkeydownで候補を再度クリアしますが、オートコンプリート用語が変更されていないため、keyupで新しい候補を提供しません。

考えられる最もハック的でない「修正」は、ガード/最適化を削除して、ライブラリが常にkeyupで新しい候補を提供することですが、これが望ましいかどうか、またはそれだけの価値があるかどうかはわかりません。

いつかオートコンプリートライブラリを書き直したいということは知っています(コードベースの中で最も古いコードの一部であり、書き直しが desperately 必要です)、なので、このバグは書き直しに着手するまで待つことができるかもしれません。

「いいね!」 5

クラッシュは一種の「無限ループ」ですか?フィードバックループに陥ったことを追跡して、すべてをクリアすることはできませんか?

「いいね!」 1

いいえ、クラッシュはヌル変数にアクセスしています。サジェストがクリアされると autocompleteOptions 変数がヌルに設定され、レンダリングされたサジェストのいずれかをタップしたときに autocompleteOptions が配列であることを期待しますが、実際にはヌルです。

これにより、別のアイデアが浮かびました。サジェストが選択されたときに autocompleteOptions がヌルかどうかを確認し、変数がヌルの場合は、指定された用語のサジェストを再取得することはできませんか?

「いいね!」 2

はい、これは良い回避策のように思えます。

「いいね!」 2

ああ、この詳細を報告しなかったなんて、自分が愚かに思えます。以前使っていたスマホは、標準でGboardが搭載されているクリーンなAndroid Oneだったので、それがずっと次のデバイス(Sammy A42 5G)にも引き継がれてきました。しかし、今日販売されているAndroidデバイスのほとんどは、デフォルトでサードパーティ製のキーボードアプリを使用しています。

この進歩を見られて嬉しいです。

「いいね!」 2

このバグの修正をマージしました。

この修正はMetaとあなたのサイト@ljppにデプロイされました。ユーザーがまだ再現できるか教えてください。

「いいね!」 5