chrome extension の Unchecked lastError value: Error: Could not establish connection. Receiving end does not exist.の対処法
土日だけ生活リズムがめっちゃ狂う。
どうも、伊藤くんです。
この度chrome extensionを開発していて、以下のようなエラーに遭遇しました。
Unchecked lastError value: Error: Could not establish connection. Receiving end does not exist.
タイミングとしては、background.jsからcontent.jsにchrome.tabs.sendMessageでメッセージを送ろうとした時。
どうやらページのローディングがまだ終わってないからダメよ!って言いたいみたいです。
めんどくさいからtry/catchで握りつぶしちまおうと思ったのですが、そこで問題発生。
こやつtry/catchを無視してくるのです。
try文の中で発生しているはずなのに、それをすり抜けてそこでプログラム全体が止まってしまうのです。
調べてみると、以下のページを発見。
https://stackoverflow.com/questions/28431505/unchecked-runtime-lasterror-when-using-chrome-api
chromeAPIは異世界で動いてるからtry/catchしても意味ないンゴよっていうのと、try/catchではなくそもそもエラーが起きないように実装してくれってばよってことみたいです。多分。
ので、try/catchに頼らずsendMessageの前にページ(タブ)のstatus、つまりローディング中であるかどうかを判定するコードを書き、エラーが起きないよう対処しました。
コードは以下です。
function waitPageLoad(callback) {
// 取得するタブの条件
const queryInfo = {
active: true,
windowId: chrome.windows.WINDOW_ID_CURRENT
};
// タブの情報を取得する
chrome.tabs.query(queryInfo, function(result) {
// 配列の先頭に現在タブの情報が入っている
const currentTab = result.shift();
if (currentTab.status === 'complete') {
// ロードが完了していたら、コールバックを実行
callback(currentTab);
} else {
setTimeout(() => {
// まだロード中だった場合は、ちょっとwaitして再帰的にこの処理を繰り返す
waitPageLoad(callback);
}, 50);
}
});
}
現在タブを取得して、それのstatusフィールドを見ます。ローディングが終わっていたらstatusフィールドが’complete’になっているので、そうなっていたらコールバック関数を実行します。ローディング中だったらstatusフィールドは’loading’とかだったと思います。
ローディング中だったら50ミリ秒待ってもっかい同じ処理をするという、ちょっと危なっかしくてダサい処理をしていますが、その辺は多めに見てください。
この関数を使う側は、以下のような感じです。
waitPageLoad((currentTab) => {
chrome.tabs.sendMessage(currentTab.id, 'content.jsへのめっせーじ', () => {});
});
これで、ページのロードが完了してからメッセージを送ることができますので、あの忌まわしいエラーは起きなくなります。
2時間くらいハマってしまったぜ。
コメントを残す