Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Reject with real Error instances like Firefox does #293

Merged
merged 9 commits into from
Mar 18, 2021
4 changes: 2 additions & 2 deletions src/browser-polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.
const makeCallback = (promise, metadata) => {
return (...callbackArgs) => {
if (extensionAPIs.runtime.lastError) {
promise.reject(extensionAPIs.runtime.lastError);
promise.reject(new Error(extensionAPIs.runtime.lastError.message));
} else if (metadata.singleCallbackArg ||
(callbackArgs.length <= 1 && metadata.singleCallbackArg !== false)) {
promise.resolve(callbackArgs[0]);
Expand Down Expand Up @@ -484,7 +484,7 @@ if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.
if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
resolve();
} else {
reject(extensionAPIs.runtime.lastError);
reject(new Error(extensionAPIs.runtime.lastError.message));
}
} else if (reply && reply.__mozWebExtensionPolyfillReject__) {
// Convert back the JSON representation of the error into
Expand Down
19 changes: 19 additions & 0 deletions test/fixtures/detect-existing-browser-api-object/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,22 @@ test("browser api object in background page", async (t) => {
t.ok(!reply.windowBrowserIsUnchanged, "window.browser API object should have been defined by the polyfill");
}
});

test("error types", async (t) => {
if (navigator.userAgent.includes("Firefox/")) {
try {
await browser.storage.sync.set({a: 'a'});
t.fail('It should throw when attempting to call storage.sync with a temporary addon ID');
} catch (error) {
t.equal(error.message, 'The storage API will not work with a temporary addon ID. Please add an explicit addon ID to your manifest. For more information see https://mzl.la/3lPk1aE.');
t.ok(error instanceof Error);
}
} else {
await new Promise(resolve => {
chrome.storage.local.set({a: 'a'.repeat(10000000)}, resolve);
});
t.ok(chrome.runtime.lastError, 'It should throw when attempting to set an object over quota');
t.equal(chrome.runtime.lastError.message, 'QUOTA_BYTES quota exceeded');
t.notOk(chrome.runtime.lastError instanceof Error);
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@
]
}
],
"permissions": []
"permissions": [
"storage"
]
}
11 changes: 7 additions & 4 deletions test/test-async-functions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

const {deepEqual, equal, fail, ok, throws} = require("chai").assert;
const {deepEqual, equal, fail, ok, throws, instanceOf} = require("chai").assert;
const sinon = require("sinon");

const {setupTestDOMWindow} = require("./setup");
Expand Down Expand Up @@ -56,7 +56,7 @@ describe("browser-polyfill", () => {
it("rejects the returned promise if chrome.runtime.lastError is not null", () => {
const fakeChrome = {
runtime: {
lastError: new Error("fake lastError"),
lastError: {message: "fake lastError"},
},
tabs: {
query: sinon.stub(),
Expand All @@ -70,8 +70,11 @@ describe("browser-polyfill", () => {

return window.browser.tabs.query({active: true}).then(
() => fail("Expected a rejected promise"),
(err) => equal(err, fakeChrome.runtime.lastError,
"Got the expected error in the rejected promise")
(err) => {
instanceOf(err, window.Error, "Expected the error to be an instance of Error");
equal(err.message, fakeChrome.runtime.lastError.message,
"Got the expected error in the rejected promise");
}
);
});
});
Expand Down