今回、私が作成したマウスジェスチャのChrome拡張機能 "Our Mouse Gesture"のManifestファイルをv2→v3に変更したことによって、発生するようになった謎のエラー
Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
に関するお話です。
「エラー発生箇所がファイルの0行目ってどういうこと?」と困惑をしたのでその対応の覚え書きとなります。
- 1. 「Uncaught (in promise) Error」は何か?
- 2.「Could not establish connection. Receiving end does not exist.」とは何か?
- 後書き
1. 「Uncaught (in promise) Error」は何か?
Manifest v2の時からそうだったのかもしれませんが、APIリファレンスでchrome.runtimeなどのコールバック関数を引数で指定するAPI関数の戻り値をよく見ると、"Promise"が返ってくると書いてあります。
この戻り値"Promise"は、API関数の引数でコールバック関数を指定しないときだけ返ってくる物のようです。
※chrome.runtime.sendMessageのAPIリファレンス https://developer.chrome.com/docs/extensions/reference/runtime/#method-sendMessage
そして、「Uncaught (in promise) Error」のメッセージは、この戻り値の "Promise" でエラーをハンドリングしていないという意味のようでした。つまり、これまでのように以下の書き方ではこのエラーメッセージが表示されてしまうという事を意味しているのだと思います。
let message = "test"; chrome.runtime.sendmessage(message, (response)=> { // コールバック関数の処理 });
そのため、"Promise" でエラーをハンドリングするためには、コールバック関数を引数では指定せずに、Promise戻り値を利用する書き方への変更が求められます。
let message = "test"; let rtnPromise = chrome.runtime.sendmessage(message); rtnPromise .then((response)=> { // コールバック関数の処理 }) .catch((error)=> { // エラー処理 )}
こうする事で、「Uncaught (in promise) Error」というエラーの発生を抑制し、その代わりにエラーが発生したときのハンドリング処理を自分で書くことができます。
2.「Could not establish connection. Receiving end does not exist.」とは何か?
前述の通りにエラーをハンドリングすると、「Uncaught (in promise) Error」という「エラーをCatchしていませんよ。」というメッセージは出てこなくなりますが、依然として「Could not establish connection. Receiving end does not exist.」というエラーは発生しています。
ではこの「Could not establish connection. Receiving end does not exist.」はどのような時に発生するのでしょうか?
現在のところ、以下のChrome APIを実行した時にこのエラーが発生することを確認しています。
- chrome.tabs.sendMessage()
let rtnPromise = chrome.tabs.sendMessage(tabid, message); rtnPromise .then((response)=> { // コールバック関数の処理 }) .catch((error)=> { // エラー処理 )}
この特定タブへメッセージを送った際に、そのタブがメッセージを受信できない状態であった場合にこのエラーが発生するようです。
2.1. エラー発生ケース1 : メッセージ送信先タブが、Chromeに関連する画面の場合
まず確実にいえることは、「chrome://」から始まるChromeが管理する画面を表示しているタブへchrome.tabs.sendMessageをした場合は確実にこのエラーが発生しました。
【例】
- chrome://newtab/ :新しいタブ画面
- chrome://extensions/ :Chrome拡張機能管理画面
そのため、対策としてはメッセージ送信先タブのURLがChromeが管理する画面の場合は、メッセージを送信しない様に制御することが考えられます。
ただ、「chrome://」から始まるURLで判別すると、Chromium Edgeに対応できないので、「http」から始まるURLの時にメッセージを送信するという判別にした方がよいと思われます。
2023/05/04追記
Chrome Webストアのページでもこのエラーが発生する事が確認されたので追記をしておきます。
- URL:https://chrome.google.com/webstore
2.2. エラー発生ケース2 : Content Scriptがメッセージを受け取れない状態(固まっている?)の場合
2つ目のケースは純粋にメッセージを受け取る側のタブのContent Scriptに何かしらの問題が発生していて、chrome.tabs.sendMessageで送られてくるメッセージを受信できない状態のときのようでした。 このエラーが発生したタブでは、私が作成したMouse Gestureが正常に動作しなくなっていたので、そこから Content Script に問題が発生しているのでは無いかと推測しました。
後書き
現時点(2022/07/11)で分かっている事を纏めてみました。
同様の問題に直面している人の助けになれたら幸いです。
最後まで読んで頂きありがとうございました。