add a callstack to errors in browser
, API
, msg
This commit is contained in:
parent
9d2854c272
commit
b132fecbcd
29
js/msg.js
29
js/msg.js
|
@ -78,12 +78,12 @@
|
||||||
|
|
||||||
send(data, target = 'extension') {
|
send(data, target = 'extension') {
|
||||||
return browser.runtime.sendMessage({data, target})
|
return browser.runtime.sendMessage({data, target})
|
||||||
.then(unwrapResponse);
|
.then(unwrapResponseFactory('send'));
|
||||||
},
|
},
|
||||||
|
|
||||||
sendTab(tabId, data, options, target = 'tab') {
|
sendTab(tabId, data, options, target = 'tab') {
|
||||||
return browser.tabs.sendMessage(tabId, {data, target}, options)
|
return browser.tabs.sendMessage(tabId, {data, target}, options)
|
||||||
.then(unwrapResponse);
|
.then(unwrapResponseFactory('sendTab'));
|
||||||
},
|
},
|
||||||
|
|
||||||
_execute(types, ...args) {
|
_execute(types, ...args) {
|
||||||
|
@ -138,9 +138,15 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwrapResponse({data, error} = {error: {message: ERR_NO_RECEIVER}}) {
|
function unwrapResponseFactory(name) {
|
||||||
|
return unwrapResponse.bind(null, new Error(`Callstack before invoking msg.${name}:`));
|
||||||
|
}
|
||||||
|
|
||||||
|
function unwrapResponse(localErr, {data, error} = {error: {message: ERR_NO_RECEIVER}}) {
|
||||||
return error
|
return error
|
||||||
? Promise.reject(Object.assign(new Error(error.message), error))
|
? Promise.reject(Object.assign(localErr, error, {
|
||||||
|
stack: `${error.stack}\n${localErr.stack}`,
|
||||||
|
}))
|
||||||
: data;
|
: data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,18 +160,23 @@
|
||||||
const bg = getExtBg() ||
|
const bg = getExtBg() ||
|
||||||
chrome.tabs && await browser.runtime.getBackgroundPage().catch(() => {});
|
chrome.tabs && await browser.runtime.getBackgroundPage().catch(() => {});
|
||||||
const message = {method: 'invokeAPI', path, args};
|
const message = {method: 'invokeAPI', path, args};
|
||||||
let res;
|
|
||||||
// content scripts, probably private tabs, and our extension tab during Chrome startup
|
// content scripts, probably private tabs, and our extension tab during Chrome startup
|
||||||
if (!bg) {
|
if (!bg) {
|
||||||
res = msg.send(message);
|
return msg.send(message);
|
||||||
} else {
|
}
|
||||||
res = deepMerge(await bg.msg._execute(TARGETS.extension, message, {
|
const err = new Error(`Callstack before invoking API.${path.join('.')}:`);
|
||||||
|
try {
|
||||||
|
return deepMerge(await bg.msg._execute(TARGETS.extension, message, {
|
||||||
frameId: 0, // false in case of our Options frame but we really want to fetch styles early
|
frameId: 0, // false in case of our Options frame but we really want to fetch styles early
|
||||||
tab: NEEDS_TAB_IN_SENDER.includes(path.join('.')) && await getOwnTab(),
|
tab: NEEDS_TAB_IN_SENDER.includes(path.join('.')) && await getOwnTab(),
|
||||||
url: location.href,
|
url: location.href,
|
||||||
}));
|
}));
|
||||||
|
} catch (bgError) {
|
||||||
|
err.stack = `${bgError.stack}\n${err.stack}`;
|
||||||
|
err.message = bgError.message;
|
||||||
|
// Not using `throw` to avoid pausing debugger when it's configured to pause on exceptions
|
||||||
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
/** @type {API} */
|
/** @type {API} */
|
||||||
|
|
|
@ -23,14 +23,20 @@
|
||||||
};
|
};
|
||||||
const promisify = function (fn, ...args) {
|
const promisify = function (fn, ...args) {
|
||||||
let res;
|
let res;
|
||||||
try {
|
|
||||||
let resolve, reject;
|
let resolve, reject;
|
||||||
|
const err = new Error();
|
||||||
|
try {
|
||||||
|
args.push((...results) => {
|
||||||
|
const {lastError} = chrome.runtime;
|
||||||
|
if (lastError) {
|
||||||
|
err.message = lastError.message;
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
/* Some callbacks have 2 parameters so we're resolving as an array in that case.
|
/* Some callbacks have 2 parameters so we're resolving as an array in that case.
|
||||||
For example, chrome.runtime.requestUpdateCheck and chrome.webRequest.onAuthRequired */
|
For example, chrome.runtime.requestUpdateCheck and chrome.webRequest.onAuthRequired */
|
||||||
args.push((...results) =>
|
resolve(results.length <= 1 ? results[0] : results);
|
||||||
chrome.runtime.lastError ?
|
}
|
||||||
reject(new Error(chrome.runtime.lastError.message)) :
|
});
|
||||||
resolve(results.length <= 1 ? results[0] : results));
|
|
||||||
fn.apply(this, args);
|
fn.apply(this, args);
|
||||||
res = new Promise((...rr) => ([resolve, reject] = rr));
|
res = new Promise((...rr) => ([resolve, reject] = rr));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user