はじめに
chromeのプラグインを作成していると、中々、原因をつかむことができなくて、困るエラーに出会います。エラーメッセージを見ても意味を理解しにくいというか、現象の原因がはっきりとメッセージに表現されていないということです。単に'undefined'と表示されても困ります。もう少し、具体的なメッセージにはならないでしょうか。どこがどう悪いからエラーになっていますとか。今回、遭遇したエラーの現象と解決策をご説明します。
現象
chrome.runtime.sendMessage()を使用して、background.jsへメッセージを送信しようとして、sendMessage()がundefinedというエラーになりました。
デバッガーで追うと、chromeのオブジェクトに、runtimeメソッドがありません。
runtimeがないから、sendMessageもないことになります。
ここで、なぜ、runtimeメソッドがないのかを具体的に示して欲しいのですが、その記述はありません。この原因を特定するまでに相当の時間がかかりました。
この現象をもう少し、追いかけてみました。
別のプラグインでは発生していません。そこで、何が違うのか、二つのプラグインをツールの差分を使って比較しましたが、これといってそれらしい原因は見当たりませんでした。
実際に呼び出しているコードは以下になります。
呼び出しているjavascriptは、プラグインではなく、iframeプレーヤーのjavascriptからです。そのため、g_EXTENSION_IDでプラグインを特定するIdを指定しています。
function get_tabId() {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(g_EXTENSION_ID, {'type': 'get_tabId', 'url': location.ancestorOrigins[0]}, (msg) => {
//応答で、tabIdを取得して、要素にセット
$("#tabId").html(msg);
resolve(msg);
});
});
}
原因
上記のコードを見ていて、ハタと気が付きました。もしかしたら、manifest.jsonの問題かなと思いました。
以下はその部分です。
"externally_connectable": {
"matches": ["https://*/*"
]
}
動作しなかった方のmanifest.jsonには、上記の設定がありませんでした。もともとは、動作していたmanifest.jsonをコピーして使用していましたが、そのプラグインでは不要のため、削除していました。
その後、再び、ある機能を追加するため、先のget_tabId()関数を導入しましたが、manifest.jsonまでは修正していませんでした。
このため、externally_connectableの指定がなかったため、sendMessage()でundefinedエラーがでていました。
しかし、このexternally_connectableの指定がないことと、sendMessage()でundefinedエラーが出ることのつながりがエラーメッセージを見ただけではわかりません。このことが、エラー原因の特定が遅れたことにつながります。
結論
今回のエラーは、manifest.jsonの指定漏れが原因でした。しかし、実際に表示されるエラーメッセージでは、その実際の原因が表示されていません。このようなエラーメッセージは他にも多くあります。中々、個々の原因までを細かく表示することはできないのでしょうか。自分に当てはめるとよくわかります。中々、そこまでは手間をかけられないですね。しかし、エラーが発生してみて、初めてわかります。もっと具体的なメッセージを出して置けばこんなに時間をかけなくてもよかったと。
あとがき
ソースコードを再利用しているとよく、このようなことが起こります。不要なコードをカットしてゆき、新規に追加するコードを書き足してゆきます。その時に設定ファイルはそのままとか、あるいは設定ファイルにもカットする箇所があり、カットしたままで、後から、再び、カットしたコードを戻すことをしているときに起こります。
この整合性をしっかりとチェックしないと、結構、無駄な時間がとられてしまいます。何度、反省してもまた、繰り返してしまいます。