Open kottkrig opened 6 years ago
Perhaps try changing this line: return Promise.resolve({ response: data }); I don't really understand promises, but if you're using async functions, I think they're dealt with automatically, and you can just say: return { response: data };
On second thoughts, that probably won't make any difference.
It could be the way you're importing it? This might bypass the check intended to stop the polyfill being applied to Firefox? The main page has suggestions about how to import it.
A couple of other suggestions: There might an issue with Webpack? (see #86) And if you don't need to support old browsers, you can drop Babel. (see #50) (Just going by others' comments. I don't know anything about either of these myself.)
Has anyone found a solution to this problem, running into this as well.
Can you share your generated bundle?
Side note, the following is incorrect if your intent is to only respond to LOREM
because the onMessage
handler is an async
function, which returns a promise by default.
browser.runtime.onMessage.addListener(async ({ kind, data }) => {
if (kind === "LOREM") {
return Promise.resolve({ response: data });
}
return false;
});
should be without async
, or simply:
browser.runtime.onMessage.addListener(async ({ kind, data }) => {
if (kind === "LOREM") {
return { response: data };
}
});
@Rob--W I am trying to send a message from a content script, if I pause the debugger just before it is about to send the message, and I send a message that is not handled:
browser.runtime.sendMessage("whatever").then(console.log.bind(console))
I get the same error.
TypeError: promise.then is not a function Stack trace: wrapPromise@resource://gre/modules/ExtensionCommon.jsm:492:7 callAsyncFunction@resource://gre/modules/ExtensionCommon.jsm:737:12 stub@resource://gre/modules/Schemas.jsm:2300:22 _callee5$@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67708:29 tryCatch@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:22601:37 invoke@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:22839:22 defineIteratorMethods/</prototype[method]@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:22653:16 step@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67526:183 _asyncToGenerator/</<@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67526:437 Promise@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:20706:7 _asyncToGenerator/<@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67526:99 init/<@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67765:20 Promise@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:20706:7 init@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67684:12 @moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67770:1 __webpack_require__@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:20:12 @moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:67280:18 __webpack_require__@moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:20:12 @moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:63:18 @moz-extension://b03cc2f6-d49c-454e-a4aa-1f4b8b3d9614/plugin.js:1:11 inject@resource://gre/modules/ExtensionContent.jsm:489:18
@rikedia Please share your generated code...
@Rob--W newsreader-extension-nl-tst.zip
@rikedia In your extension, the native Promise
constructor has been replaced with something else. Don't do that (e.g. by removing babel-polyfill
; both Chrome and Firefox support async
/ await
these days).
The fact that replacing the global Promise
constructor breaks sendMessage
is probably an unintended bug. I have reported it upstream at https://bugzilla.mozilla.org/show_bug.cgi?id=1456531 .
@Rob--W Thanks for pointing that out.
I fixed my problems by removing babel-polyfill and adding babel-plugin-transform-runtime with the polyfill option set to false.
{
...
"plugins": [
...
[
"transform-runtime",
{
"polyfill": false,
"regenerator": true
}
]
]
}
Thanks @Rob--W and @rikedia. That helped me get rid of the "promise.then is not a function" error but I'm now getting another error in Firefox:
Unhandled promise rejection TypeError: "_ref2 is undefined"
(It works in Chrome)
The generated files are available in this gist. And here is an excerpt with my function from content_script.js
:
var sendMessage = function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
var _ref2, response;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _webextensionPolyfill2.default.runtime.sendMessage({
kind: "LOREM",
data: "ipsum"
});
case 2:
_ref2 = _context.sent;
response = _ref2.response;
console.log("content_script: response:", response);
case 5:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function sendMessage() {
return _ref.apply(this, arguments);
};
}(); // content_script.js
I've added the transform-runtime to my webpack config and removed the babel-polyfill:
const path = require("path");
module.exports = {
entry: {
background_page: ["./src/background_page.js"],
content_script: ["./src/content_script.js"]
},
output: {
path: path.resolve(__dirname + "/dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["babel-preset-env"],
plugins: [
[
"babel-plugin-transform-runtime",
{ polyfill: false, regenerator: true }
]
]
}
}
}
]
}
};
Have you tried following the suggestion from https://github.com/mozilla/webextension-polyfill/issues/105#issuecomment-383876541 ?
The auto-generated code is difficult to read due to the replaced async
/await
. Can you share a zip file or repo with the minimal project to reproduce the bug?
I got it working by changing my webpack setup to use "babel-preset-env" with my current node as the target so that it uses native async/await.
Thanks @Rob--W for the help!
My updated webpack config for completeness:
const path = require("path");
module.exports = {
entry: {
background_page: ["./src/background_page.js"],
content_script: ["./src/content_script.js"]
},
output: {
path: path.resolve(__dirname + "/dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: [["babel-preset-env", { targets: { node: "current" } }]]
}
}
}
]
}
};
Closing this since this is not an issue with the polyfill, but with Firefox * as explained in https://github.com/mozilla/webextension-polyfill/issues/105#issuecomment-383990462 .
The solution is also described in the previous comments: change the webpack/babel configuration to not replace the Promise
global.
* The polyfill is a no-op in Firefox. We will document this more clearly and close #55 in the future.
@Rob--W I was also facing similar issue in Firefox. browser.runtime.onMessage.addListener
should be waiting for the Promise
to resolve and the return to the browser.runtime.sendMessage
. It worked in Chrome but in Firefox it returned and didn't wait. I was using babel-polyfill
. Following your solution helped and now the extension works as expected in all the browsers.
Thank you. 👍
@abhijithvijayan - Just had the exact same issue. Took a few hours to get to this thread and this point.
I was getting an unhandled promise rejection and my sendMessage
call was being immediately fulfilled.
This is a really nasty side effect of the usage of the Promise polyfill.
My .babelrc
now looks like this:
module.exports = {
presets: [
["@babel/preset-env", {
corejs: 3,
debug: false,
exclude: [
"es.promise",
"es.promise.finally"
],
loose: true,
spec: true,
targets: {
browsers: [
"last 2 Chrome versions",
"last 2 Firefox versions"
]
},
useBuiltIns: "usage"
}]
]
}
@Rob--W I think that it may be reasonable to explicitly document the "TypeError: promise.then is not a function" error in one of the following sections of the README.md file e.g.:
even if this isn't technically a issue of the webextension-polyfill, so that an addon developer that has this issue doesn't need to find this closed issue to know how to fix it.
Let's update the docs.
Preferably this should be fixed in Firefox. The validation in the extension framework is stricter than the JS engine's (i.e. in situations where promises are used, thenables are perfectly fine, whereas in the extension framework we don't accept them currently).
I'm getting the following error in Firefox when I try to send a runtime message from a content script to a background script:
I'm using webpack with babel-polyfill to include the generator runtime:
It works fine in Chrome. What am I missing?