phpjs
Version:
100 lines (93 loc) • 4.38 kB
JavaScript
function set_exception_handler(callback) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// * example 1: set_exception_handler(function (exceptionObj) {alert(exceptionObj.getMessage());});
// * returns 1: null
var that = this, oldHandlerName = '';
var _getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
if (typeof callback === 'string') {
callback = this.window[callback];
}
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
// END REDUNDANT
// For return
oldHandlerName = this.php_js.exception_handler ? _getFuncName(this.php_js.exception_handler) : null;
if (this.php_js.exception_handler) { // Fix: Any potential built-in ones (e.g., via ini) to fall back on, as the PHP manual suggests?
this.php_js.previous_exception_handler = this.php_js.exception_handler; // usable by restore_exception_handler()
}
// Set callback
this.php_js.exception_handler = callback;
// Make available a global Exception class (see _experimental/language)
if (!this.window.Exception) {
this.window.Exception = function(message, code) {
// These four are supposed to be protected (extendable, but not public)
this.message = message || '';
this.code = code || 0; // user defined exception code
// Fix: Just putting something here for the next two (not PHP-style)... Can over-ride if extending, however;
// in Mozilla, error objects (e.g., if you're in a catch block), have these properties which might be used to
// add to the object after instantiation (or during instantiation if extending the exception): fileName,
// lineNumber, stack; actually, should use PHP Error object for these anyways if following the PHP API
// since it does have these properties
// Note that for the trace, however, in Mozilla the stack property is a string, and getTrace() needs the items
// parsed as an array; this might be doable by setting the exception object's trace property to
// "e.stack.replace(/\n$/, '').split('\n');" if 'e' is a JavaScript exception
this.file = this.window.href.location; // source filename of exception
this.line = 0; // source line of exception
this.string = 'Exception'; // private string; Internal Exception name
this.name = 'Exception'; // To fit the JavaScript Error interface, user could also add a custom name property.
that.php_js.exception_handler(this);
};
this.window.Exception.prototype = {
constructor: this.window.Exception,
// FINAL (not supposed to extend the following 6 methods)
getMessage: function() { // message of exception
return this.message;
},
getCode: function() { // code of exception
return this.code;
},
getFile: function() { // source filename
return this.file;
},
getLine: function() { // source line
return this.line;
},
getTrace: function() { // an array of the backtrace()
// Todo: add trace for Mozilla, etc.
var ret = '';
for (var i = 0; i < this.trace.length; i++) {
ret += '\n#' + i + ' ' + this.trace[i];
}
return ret.slice(1);
// return this.trace; // should be an array (especially so that getTraceAsString() works properly)
},
getTraceAsString: function() { // formatted string of trace
// Todo: add trace for Mozilla, etc.
return this.trace.toString();
},
// Overrideable
__toString: function() { // formatted string for display
// PHP-style
return "exception '" + this.string + "' with message '" + this.getMessage() + "' in " +
this.getFile() + ':' + this.getLine() + '\nStack trace:\n' + this.getTraceAsString();
// return this.name+': '+this.message; // this works also, but in JavaScript-style
},
// For JavaScript interface/behavior:
toString: function() {
return this.__toString(); // We implement on toString() to implement JavaScript Error interface
},
// PRIVATE FINAL METHODS
__clone: function() {
throw 'Fatal exception: exceptions are not clonable';
}
};
}
return oldHandlerName;
}