Better error and promise rejections handling

This commit is contained in:
Ilya Ig. Petrov 2016-11-20 03:33:18 -08:00
parent 3b891f82b4
commit 05c6deadf8
2 changed files with 116 additions and 45 deletions

View File

@ -81,7 +81,7 @@ window.antiCensorRu = {
return chrome.storage.local.clear(
() => chrome.storage.local.set(
onlySettable,
() => cb && cb(chrome.runtime.lastError, onlySettable)
chromified(cb, onlySettable)
)
);
@ -90,15 +90,18 @@ window.antiCensorRu = {
pullFromStorage(cb) {
chrome.storage.local.get(null, (storage) => {
const err = checkChromeError();
if (!err) {
console.log('Pulled from storage:', storage);
for(const key of Object.keys(storage)) {
this[key] = storage[key];
}
}
console.log('Synced with storage, any callback?', !!cb);
if (cb) {
cb(chrome.runtime.lastError, storage);
}
return cb && cb(err, storage);
});
},
@ -109,39 +112,51 @@ window.antiCensorRu = {
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
}
var pacSetPromise = new Promise(
const pacSetPromise = new Promise(
(resolve, reject) => setPacScriptFromProvider(
this.pacProvider,
(err, res) => {
if (err) {
return reject(err);
}
if (!err) {
this.lastPacUpdateStamp = Date.now();
this.ifFirstInstall = false;
this.setAlarms();
}
return resolve([err, res]);
return resolve(res);
}
)
);
return updatePacProxyIps(
const ipsPromise = new Promise(
(resolve, reject) => updatePacProxyIps(
this.pacProvider,
(ipsError) => {
if (ipsError && ipsError.clarification) {
ipsError.clarification.ifNotCritical = true;
}
pacSetPromise.then(
(res) => this.pushToStorage(
(pushError) => pushError ? cb(pushError) : cb(ipsError, res)
),
cb
return resolve([ipsError]);
}
)
);
Promise.all([pacSetPromise, ipsPromise]).then(
([[pacErr, pacRes], [ipsErr]]) => {
if (pacErr && ipsErr) {
return cb(pacErr, pacRes);
}
return cb(pacErr || ipsErr);
this.pushToStorage(
(pushErr) => cb(pacErr || ipsErr || pushErr, pacRes)
);
}
);
},
_pacUpdatePeriodInMinutes: 4*60,
@ -168,6 +183,7 @@ window.antiCensorRu = {
installPac(key, cb) {
console.log('Installing PAC');
if(typeof(key) === 'function') {
cb = key;
key = undefined;
@ -178,6 +194,7 @@ window.antiCensorRu = {
}
return this.syncWithPacProvider(cb);
},
clearPac(cb) {
@ -188,8 +205,13 @@ window.antiCensorRu = {
{},
() => {
const err = checkChromeError();
if (err) {
return cb(err);
}
this.currentPacProviderKey = undefined;
return this.pushToStorage(cb);
}
)
);
@ -274,27 +296,59 @@ chrome.storage.local.get(null, (oldStorage) => {
**/
});
function asyncLogGroup() {
function asyncLogGroup(...args) {
const args = [].slice.apply(arguments);
const cb = args.pop() || (() => {});
console.group.apply(console, args);
return function() {
return function(...cbArgs) {
console.groupEnd();
console.log('Group finished.');
return cb.apply(this, arguments);
return cb.apply(this, cbArgs);
}
}
function checkChromeError(betterStack) {
// Chrome API calls your cb in a context different from the point of API method invokation.
const err = chrome.runtime.lastError || chrome.extension.lastError || null;
if (err) {
const args = ['API returned error:', err];
if (betterStack) {
args.push('\n' + betterStack);
}
console.warn.apply(console, args);
}
return err;
}
function chromified(cb, ...replaceArgs) {
const stack = (new Error()).stack;
// Take error first callback and covert it to chrome api callback.
return function(...args) {
if (replaceArgs.length) {
args = replaceArgs;
}
const err = checkChromeError(stack);
return cb && cb.call(this, err, ...args);
};
}
function httpGet(url, cb) {
const start = Date.now();
return fetch(url).then(
(res) => {
const textCb = (err) => cb && res.text().then( text => cb(err, text), cb );
const textCb =
(err) => cb && res.text()
.then( (text) => cb(err, text), cb );
const status = res.status;
if ( !( status >= 200 && status < 300 || status === 304 ) ) {
res.clarification = {message: 'Получен ответ с неудачным HTTP-кодом ' + status + '.'};
@ -302,11 +356,13 @@ function httpGet(url, cb) {
}
console.log('GETed with success:', url, Date.now() - start);
return textCb();
},
(err) => {
err.clarification = {message: 'Что-то не так с сетью, проверьте соединение.'};
return cb && cb(err);
}
);
}
@ -457,9 +513,6 @@ function setPacScriptFromProvider(provider, cb) {
return cb(err);
}
console.log('Clearing chrome proxy settings...');
return chrome.proxy.settings.clear({}, () => {
const config = {
mode: 'pac_script',
pacScript: {
@ -468,8 +521,22 @@ function setPacScriptFromProvider(provider, cb) {
}
};
console.log('Setting chrome proxy settings...');
chrome.proxy.settings.set( {value: config}, cb );
});
chrome.proxy.settings.set( {value: config}, chromified(cb) );
}
);
}
window.addEventListener('error', (err) => {
console.error('Global error');
});
window.addEventListener('unhandledrejection', (event) => {
console.warn('Unhandled rejection. Throwing error.');
event.preventDefault();
throw event.reason;
});

View File

@ -96,7 +96,12 @@ chrome.runtime.getBackgroundPage( backgroundPage => {
enableDisableInputs();
setStatusTo('Установка...');
antiCensorRu.installPac(pacKey, (err) => {
if (err) {
backgroundPage.console.log('Popup callback...');
if (!err) {
setStatusTo('PAC-скрипт установлен.');
}
else {
var ifNotCritical = err.clarification && err.clarification.ifNotCritical;
var message = '';
@ -127,8 +132,7 @@ chrome.runtime.getBackgroundPage( backgroundPage => {
}
return false;
};
} else
setStatusTo('PAC-скрипт установлен.');
}
enableDisableInputs();
});
}