fix: Reject with real Error instances like Firefox does (#293)
Co-authored-by: Federico Brigante <me@fregante.com>
This commit is contained in:
Родитель
fa4b26f406
Коммит
5ab825b83f
|
@ -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]);
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,5 +19,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"permissions": []
|
||||
"permissions": [
|
||||
"storage"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
@ -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(),
|
||||
|
@ -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");
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче