extensionSystem: Be saner at error handling
Use our native JS error system in the "extension system" API, only using the signal/log-based error reporting at the last mile. Additionally, delete the directory if loading the extension failed, and report the error back over DBus. https://bugzilla.gnome.org/show_bug.cgi?id=679099
This commit is contained in:
parent
7949397958
commit
c99e8eb29d
@ -111,7 +111,15 @@ function gotExtensionZipFile(session, message, uuid, callback, errback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
let extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||||
ExtensionSystem.loadExtension(extension);
|
|
||||||
|
try {
|
||||||
|
ExtensionSystem.loadExtension(extension);
|
||||||
|
} catch(e) {
|
||||||
|
uninstallExtensionFromUUID(uuid);
|
||||||
|
errback('LoadExtensionError', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ function disableExtension(uuid) {
|
|||||||
try {
|
try {
|
||||||
ExtensionUtils.extensions[uuid].stateObj.disable();
|
ExtensionUtils.extensions[uuid].stateObj.disable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logExtensionError(uuid, e.toString());
|
logExtensionError(uuid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,19 +72,14 @@ function disableExtension(uuid) {
|
|||||||
theme.unload_stylesheet(extension.stylesheet.get_path());
|
theme.unload_stylesheet(extension.stylesheet.get_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
extension.stateObj.disable();
|
||||||
extension.stateObj.disable();
|
|
||||||
} catch(e) {
|
|
||||||
logExtensionError(uuid, e.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < order.length; i++) {
|
for (let i = 0; i < order.length; i++) {
|
||||||
let uuid = order[i];
|
let uuid = order[i];
|
||||||
try {
|
try {
|
||||||
ExtensionUtils.extensions[uuid].stateObj.enable();
|
ExtensionUtils.extensions[uuid].stateObj.enable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logExtensionError(uuid, e.toString());
|
logExtensionError(uuid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,42 +102,38 @@ function enableExtension(uuid) {
|
|||||||
|
|
||||||
extensionOrder.push(uuid);
|
extensionOrder.push(uuid);
|
||||||
|
|
||||||
try {
|
extension.stateObj.enable();
|
||||||
extension.stateObj.enable();
|
|
||||||
} catch(e) {
|
|
||||||
logExtensionError(uuid, e.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let stylesheetFile = extension.dir.get_child('stylesheet.css');
|
let stylesheetFile = extension.dir.get_child('stylesheet.css');
|
||||||
if (stylesheetFile.query_exists(null)) {
|
if (stylesheetFile.query_exists(null)) {
|
||||||
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
||||||
try {
|
theme.load_stylesheet(stylesheetFile.get_path());
|
||||||
theme.load_stylesheet(stylesheetFile.get_path());
|
extension.stylesheet = stylesheetFile;
|
||||||
extension.stylesheet = stylesheetFile;
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, 'Stylesheet parse error: ' + e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension.state = ExtensionState.ENABLED;
|
extension.state = ExtensionState.ENABLED;
|
||||||
_signals.emit('extension-state-changed', extension);
|
_signals.emit('extension-state-changed', extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
function logExtensionError(uuid, message, state) {
|
function logExtensionError(uuid, error) {
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
if (!extension)
|
if (!extension)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let message = '' + error;
|
||||||
|
|
||||||
|
if (error.state)
|
||||||
|
extension.state = error.state;
|
||||||
|
else
|
||||||
|
extension.state = ExtensionState.ERROR;
|
||||||
|
|
||||||
if (!extension.errors)
|
if (!extension.errors)
|
||||||
extension.errors = [];
|
extension.errors = [];
|
||||||
|
|
||||||
extension.errors.push(message);
|
|
||||||
log('Extension "%s" had error: %s'.format(uuid, message));
|
log('Extension "%s" had error: %s'.format(uuid, message));
|
||||||
state = state || ExtensionState.ERROR;
|
|
||||||
_signals.emit('extension-state-changed', { uuid: uuid,
|
_signals.emit('extension-state-changed', { uuid: uuid,
|
||||||
error: message,
|
error: message,
|
||||||
state: state });
|
state: extension.state });
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadExtension(extension) {
|
function loadExtension(extension) {
|
||||||
@ -150,9 +141,9 @@ function loadExtension(extension) {
|
|||||||
extension.state = ExtensionState.ERROR;
|
extension.state = ExtensionState.ERROR;
|
||||||
|
|
||||||
if (ExtensionUtils.isOutOfDate(extension)) {
|
if (ExtensionUtils.isOutOfDate(extension)) {
|
||||||
logExtensionError(extension.uuid, 'extension is not compatible with current GNOME Shell and/or GJS version', ExtensionState.OUT_OF_DATE);
|
let error = new Error('extension is not compatible with current GNOME Shell and/or GJS version');
|
||||||
extension.state = ExtensionState.OUT_OF_DATE;
|
error.state = ExtensionState.OUT_OF_DATE;
|
||||||
return;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
|
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
|
||||||
@ -192,45 +183,24 @@ function initExtension(uuid) {
|
|||||||
throw new Error("Extension was not properly created. Call loadExtension first");
|
throw new Error("Extension was not properly created. Call loadExtension first");
|
||||||
|
|
||||||
let extensionJs = dir.get_child('extension.js');
|
let extensionJs = dir.get_child('extension.js');
|
||||||
if (!extensionJs.query_exists(null)) {
|
if (!extensionJs.query_exists(null))
|
||||||
logExtensionError(uuid, 'Missing extension.js');
|
throw new Error('Missing extension.js');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let extensionModule;
|
let extensionModule;
|
||||||
let extensionState = null;
|
let extensionState = null;
|
||||||
try {
|
|
||||||
ExtensionUtils.installImporter(extension);
|
ExtensionUtils.installImporter(extension);
|
||||||
extensionModule = extension.imports.extension;
|
extensionModule = extension.imports.extension;
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, '' + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extensionModule.init) {
|
if (extensionModule.init) {
|
||||||
try {
|
extensionState = extensionModule.init(extension);
|
||||||
extensionState = extensionModule.init(extension);
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, 'Failed to evaluate init function:' + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extensionState)
|
if (!extensionState)
|
||||||
extensionState = extensionModule;
|
extensionState = extensionModule;
|
||||||
extension.stateObj = extensionState;
|
extension.stateObj = extensionState;
|
||||||
|
|
||||||
if (!extensionState.enable) {
|
|
||||||
logExtensionError(uuid, 'missing \'enable\' function');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!extensionState.disable) {
|
|
||||||
logExtensionError(uuid, 'missing \'disable\' function');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extension.state = ExtensionState.DISABLED;
|
extension.state = ExtensionState.DISABLED;
|
||||||
|
|
||||||
_signals.emit('extension-loaded', uuid);
|
_signals.emit('extension-loaded', uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +212,11 @@ function onEnabledExtensionsChanged() {
|
|||||||
newEnabledExtensions.filter(function(uuid) {
|
newEnabledExtensions.filter(function(uuid) {
|
||||||
return enabledExtensions.indexOf(uuid) == -1;
|
return enabledExtensions.indexOf(uuid) == -1;
|
||||||
}).forEach(function(uuid) {
|
}).forEach(function(uuid) {
|
||||||
enableExtension(uuid);
|
try {
|
||||||
|
enableExtension(uuid);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(extension.uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find and disable all the newly disabled extensions: UUIDs found in the
|
// Find and disable all the newly disabled extensions: UUIDs found in the
|
||||||
@ -250,7 +224,11 @@ function onEnabledExtensionsChanged() {
|
|||||||
enabledExtensions.filter(function(item) {
|
enabledExtensions.filter(function(item) {
|
||||||
return newEnabledExtensions.indexOf(item) == -1;
|
return newEnabledExtensions.indexOf(item) == -1;
|
||||||
}).forEach(function(uuid) {
|
}).forEach(function(uuid) {
|
||||||
disableExtension(uuid);
|
try {
|
||||||
|
disableExtension(uuid);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(extension.uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
enabledExtensions = newEnabledExtensions;
|
enabledExtensions = newEnabledExtensions;
|
||||||
@ -262,7 +240,11 @@ function loadExtensions() {
|
|||||||
|
|
||||||
let finder = new ExtensionUtils.ExtensionFinder();
|
let finder = new ExtensionUtils.ExtensionFinder();
|
||||||
finder.connect('extension-found', function(signals, extension) {
|
finder.connect('extension-found', function(signals, extension) {
|
||||||
loadExtension(extension);
|
try {
|
||||||
|
loadExtension(extension);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(extension.uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
finder.scanExtensions();
|
finder.scanExtensions();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user