fix: Reject with real Error instances like Firefox does (#293)
Co-authored-by: Federico Brigante <me@fregante.com>
This commit is contained in:
parent
fa4b26f406
commit
5ab825b83f
|
@ -95,7 +95,7 @@ if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.
|
||||||
const makeCallback = (promise, metadata) => {
|
const makeCallback = (promise, metadata) => {
|
||||||
return (...callbackArgs) => {
|
return (...callbackArgs) => {
|
||||||
if (extensionAPIs.runtime.lastError) {
|
if (extensionAPIs.runtime.lastError) {
|
||||||
promise.reject(extensionAPIs.runtime.lastError);
|
promise.reject(new Error(extensionAPIs.runtime.lastError.message));
|
||||||
} else if (metadata.singleCallbackArg ||
|
} else if (metadata.singleCallbackArg ||
|
||||||
(callbackArgs.length <= 1 && metadata.singleCallbackArg !== false)) {
|
(callbackArgs.length <= 1 && metadata.singleCallbackArg !== false)) {
|
||||||
promise.resolve(callbackArgs[0]);
|
promise.resolve(callbackArgs[0]);
|
||||||
|
@ -484,7 +484,7 @@ if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.
|
||||||
if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
|
if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
reject(extensionAPIs.runtime.lastError);
|
reject(new Error(extensionAPIs.runtime.lastError.message));
|
||||||
}
|
}
|
||||||
} else if (reply && reply.__mozWebExtensionPolyfillReject__) {
|
} else if (reply && reply.__mozWebExtensionPolyfillReject__) {
|
||||||
// Convert back the JSON representation of the error into
|
// Convert back the JSON representation of the error into
|
||||||
|
|
|
@ -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");
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -19,5 +19,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions": []
|
"permissions": [
|
||||||
|
"storage"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"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 sinon = require("sinon");
|
||||||
|
|
||||||
const {setupTestDOMWindow} = require("./setup");
|
const {setupTestDOMWindow} = require("./setup");
|
||||||
|
@ -56,7 +56,7 @@ describe("browser-polyfill", () => {
|
||||||
it("rejects the returned promise if chrome.runtime.lastError is not null", () => {
|
it("rejects the returned promise if chrome.runtime.lastError is not null", () => {
|
||||||
const fakeChrome = {
|
const fakeChrome = {
|
||||||
runtime: {
|
runtime: {
|
||||||
lastError: new Error("fake lastError"),
|
lastError: {message: "fake lastError"},
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
query: sinon.stub(),
|
query: sinon.stub(),
|
||||||
|
@ -70,8 +70,11 @@ describe("browser-polyfill", () => {
|
||||||
|
|
||||||
return window.browser.tabs.query({active: true}).then(
|
return window.browser.tabs.query({active: true}).then(
|
||||||
() => fail("Expected a rejected promise"),
|
() => fail("Expected a rejected promise"),
|
||||||
(err) => equal(err, fakeChrome.runtime.lastError,
|
(err) => {
|
||||||
"Got the expected error in the rejected promise")
|
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");
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue