luci-base: luci.js: consolidate error handling
Add a new function L.error() which creates and throws a custom error object with stack information and given type. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
26e54bb01f
commit
ef187d5238
1 changed files with 52 additions and 26 deletions
|
@ -451,6 +451,43 @@
|
||||||
window.cbi_init = function() {};
|
window.cbi_init = function() {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
error: function(type, fmt /*, ...*/) {
|
||||||
|
var e = null,
|
||||||
|
msg = fmt ? String.prototype.format.apply(fmt, this.varargs(arguments, 2)) : null,
|
||||||
|
stack = null;
|
||||||
|
|
||||||
|
if (type instanceof Error) {
|
||||||
|
e = type;
|
||||||
|
stack = (e.stack || '').split(/\n/);
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
e.message = msg + ': ' + e.message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e = new (window[type || 'Error'] || Error)(msg || 'Unspecified error');
|
||||||
|
e.name = type || 'Error';
|
||||||
|
|
||||||
|
try { throw new Error('stacktrace') }
|
||||||
|
catch (e2) { stack = (e2.stack || '').split(/\n/) }
|
||||||
|
|
||||||
|
/* IE puts the exception message into the first line */
|
||||||
|
if (stack[0] == 'Error: stacktrace')
|
||||||
|
stack.shift();
|
||||||
|
|
||||||
|
/* Pop L.error() invocation from stack */
|
||||||
|
stack.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append shortened & beautified stacktrace to message */
|
||||||
|
e.message += '\n' + stack.join('\n')
|
||||||
|
.replace(/(.*?)@(.+):(\d+):(\d+)/g, ' at $1 ($2:$3:$4)');
|
||||||
|
|
||||||
|
if (window.console && console.debug)
|
||||||
|
console.debug(e);
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
},
|
||||||
|
|
||||||
/* Class require */
|
/* Class require */
|
||||||
require: function(name, from) {
|
require: function(name, from) {
|
||||||
var L = this, url = null, from = from || [];
|
var L = this, url = null, from = from || [];
|
||||||
|
@ -459,8 +496,9 @@
|
||||||
if (classes[name] != null) {
|
if (classes[name] != null) {
|
||||||
/* Circular dependency */
|
/* Circular dependency */
|
||||||
if (from.indexOf(name) != -1)
|
if (from.indexOf(name) != -1)
|
||||||
throw new Error('Circular dependency: class "%s" depends on "%s"'
|
L.error('DependencyError',
|
||||||
.format(name, from.join('" which depends on "')));
|
'Circular dependency: class "%s" depends on "%s"',
|
||||||
|
name, from.join('" which depends on "'));
|
||||||
|
|
||||||
return classes[name];
|
return classes[name];
|
||||||
}
|
}
|
||||||
|
@ -472,14 +510,14 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (url == null)
|
if (url == null)
|
||||||
throw new Error('Cannot find url of luci.js');
|
L.error('InternalError', 'Cannot find url of luci.js');
|
||||||
|
|
||||||
from = [ name ].concat(from);
|
from = [ name ].concat(from);
|
||||||
|
|
||||||
var compileClass = function(res) {
|
var compileClass = function(res) {
|
||||||
if (!res.ok)
|
if (!res.ok)
|
||||||
throw new Error('HTTP error %d while loading class file "%s"'
|
L.error('NetworkError',
|
||||||
.format(res.status, url));
|
'HTTP error %d while loading class file "%s"', res.status, url);
|
||||||
|
|
||||||
var source = res.text(),
|
var source = res.text(),
|
||||||
reqmatch = /(?:^|\n)[ \t]*(?:["']require[ \t]+(\S+)(?:[ \t]+as[ \t]+([a-zA-Z_]\S*))?["']);/g,
|
reqmatch = /(?:^|\n)[ \t]*(?:["']require[ \t]+(\S+)(?:[ \t]+as[ \t]+([a-zA-Z_]\S*))?["']);/g,
|
||||||
|
@ -501,16 +539,15 @@
|
||||||
.format(args, source, res.url));
|
.format(args, source, res.url));
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
throw new SyntaxError('%s\n in %s:%s'
|
L.error('SyntaxError', '%s\n in %s:%s',
|
||||||
.format(error.message, res.url, error.lineNumber || '?'));
|
error.message, res.url, error.lineNumber || '?');
|
||||||
}
|
}
|
||||||
|
|
||||||
_factory.displayName = toCamelCase(name + 'ClassFactory');
|
_factory.displayName = toCamelCase(name + 'ClassFactory');
|
||||||
_class = _factory.apply(_factory, [window, document, L].concat(instances));
|
_class = _factory.apply(_factory, [window, document, L].concat(instances));
|
||||||
|
|
||||||
if (!Class.isSubclass(_class))
|
if (!Class.isSubclass(_class))
|
||||||
throw new TypeError('"%s" factory yields invalid constructor'
|
L.error('TypeError', '"%s" factory yields invalid constructor', name);
|
||||||
.format(name));
|
|
||||||
|
|
||||||
if (_class.displayName == 'AnonymousClass')
|
if (_class.displayName == 'AnonymousClass')
|
||||||
_class.displayName = toCamelCase(name + 'Class');
|
_class.displayName = toCamelCase(name + 'Class');
|
||||||
|
@ -523,8 +560,9 @@
|
||||||
ptr = ptr[parts[i]];
|
ptr = ptr[parts[i]];
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
throw new Error('Parent "%s" for class "%s" is missing'
|
L.error('DependencyError',
|
||||||
.format(parts.slice(0, i).join('.'), name));
|
'Parent "%s" for class "%s" is missing',
|
||||||
|
parts.slice(0, i).join('.'), name);
|
||||||
|
|
||||||
classes[name] = ptr[parts[i]] = instance;
|
classes[name] = ptr[parts[i]] = instance;
|
||||||
|
|
||||||
|
@ -562,7 +600,7 @@
|
||||||
}, _('To login…')))
|
}, _('To login…')))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Promise.reject(new Error('Session expired'));
|
L.error('AuthenticationError', 'Session expired');
|
||||||
});
|
});
|
||||||
|
|
||||||
originalCBIInit();
|
originalCBIInit();
|
||||||
|
@ -570,19 +608,7 @@
|
||||||
|
|
||||||
document.dispatchEvent(new CustomEvent('luci-loaded'));
|
document.dispatchEvent(new CustomEvent('luci-loaded'));
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
var msg = (error.stack || '').replace(/(.+?)@(.+):(\d+):(\d+)/g,
|
alert('LuCI class loading error:\n' + error);
|
||||||
' at $1 ($2:$3:$4)');
|
|
||||||
|
|
||||||
if (msg.indexOf(error.message) == -1)
|
|
||||||
msg = error.message + '\n' + msg;
|
|
||||||
|
|
||||||
if (error.name && msg.indexOf(error.name) != 0)
|
|
||||||
msg = error.name + ': ' + msg;
|
|
||||||
|
|
||||||
alert('LuCI class loading error:\n' + msg);
|
|
||||||
|
|
||||||
if (window.console && console.debug)
|
|
||||||
console.debug(error);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -831,7 +857,7 @@
|
||||||
cancel: function() { delete this.active },
|
cancel: function() { delete this.active },
|
||||||
busy: function() { return (this.active === true) },
|
busy: function() { return (this.active === true) },
|
||||||
abort: function() {},
|
abort: function() {},
|
||||||
send_form: function() { throw 'Not implemented' },
|
send_form: function() { L.error('InternalError', 'Not implemented') },
|
||||||
});
|
});
|
||||||
|
|
||||||
XHR.get = function() { return window.L.get.apply(window.L, arguments) };
|
XHR.get = function() { return window.L.get.apply(window.L, arguments) };
|
||||||
|
|
Loading…
Reference in a new issue