1 //jls.loader.provide('jls.lang.Exception'); 2 3 jls.lang.Exception = jls.lang.Class.create(/** @lends jls.lang.Exception.prototype */ 4 { 5 /** 6 * @param {String} [message] The detail message. 7 * @param {Object} [cause] The cause. 8 * @constructs 9 * @class Provide the base Exception. 10 */ 11 initialize : function(message, cause, name) { 12 /** 13 * The detail message 14 * 15 * @private 16 * @type String 17 */ 18 this._message = message || null; 19 /** 20 * The cause 21 * 22 * @private 23 * @type Object 24 */ 25 this._cause = null; 26 if (cause) { 27 this._cause = jls.lang.Exception.wrap(cause); 28 } 29 /* 30 * Generate a JS Error to get the stacktrace. 31 * The error fields are: name, message, fileName, lineNumber, stack 32 * Then remove extraenous stack information. 33 */ 34 this._stack = jls.lang.Exception.getStackFromError(new Error()); 35 this._stack.shift(); // Remove Error stack 36 this._name = name || null; 37 }, 38 /** 39 * Returns the cause of this exception or null if the cause is nonexistent or unknown. The cause is the exception that caused this 40 * exception to get thrown. 41 * 42 * @returns {Object} The cause. 43 */ 44 getCause : function() { 45 return this._cause; 46 }, 47 /** 48 * Returns the detail message string of this exception. 49 * 50 * @returns {String} The detail message. 51 */ 52 getMessage : function() { 53 return this._message; 54 }, 55 getName : function() { 56 return this._name || jls.loader.getClassname(this) || 'jls.lang.Exception'; 57 }, 58 /** 59 * Returns the stack trace of this exception. 60 * 61 * @returns {Array} The stack trace. 62 */ 63 getStackTrace : function() { 64 return this._stack; 65 }, 66 /** 67 * Prints this exception and its stacktrace. 68 * 69 * @param {jls.io.PrintStream} [ps] The print stream to use. 70 */ 71 printStackTrace : function(ps) { 72 ps = ps || jls.lang.System.out; 73 var last = null; 74 for (var e = this; e != null; e = e.getCause()) { 75 if (e == this) { 76 ps.println(e.toString()); 77 } else { 78 ps.println('Caused by: ' + e.toString()); 79 } 80 var st = e.getStackTrace(); 81 var steStr = null; 82 for (var i = 0; i < st.length; i++) { 83 var ste = st[i] 84 steStr = '\tat ' + ste.fileName + ':' + ste.lineNumber; 85 if (ste.arguments && (ste.arguments.length > 2)) { 86 steStr += ' called with ' + ste.arguments; 87 } 88 if (steStr == last) { 89 ps.println('\t... ' + (st.length - i) + ' more'); 90 break; 91 } 92 ps.println(steStr); 93 } 94 last = steStr; 95 } 96 }, 97 /** 98 * Returns a short description of this exception. 99 * 100 * @returns {String} The detail message. 101 */ 102 toString : function() { 103 var msg = this.getMessage(); 104 if (msg == null) { 105 return this.getName(); 106 } else { 107 return this.getName() + ': ' + msg; 108 } 109 } 110 }); 111 112 Object.extend(jls.lang.Exception, /** @lends jls.lang.Exception */ 113 { 114 wrap : function(e) { 115 if (e instanceof jls.lang.Exception) { 116 return e; 117 } else if ((e instanceof Error) || (e instanceof TypeError) || (e instanceof SyntaxError)) { 118 var ex = new jls.lang.Exception(e.message, undefined, e.name); 119 ex._stack = jls.lang.Exception.getStackFromError(e); 120 return ex; 121 } else { 122 return new jls.lang.Exception(e == null ? undefined : e.toString()); 123 } 124 }, 125 getStackFromError : function(e) { 126 var eStack = e.stack.split('\n'); 127 var stack = []; 128 for (var i = 0; i < eStack.length; i++) { 129 if (eStack[i].length == 0) { 130 continue; 131 } 132 var ste = eStack[i].split('@'); 133 if (ste[1] == ':0') { 134 continue; 135 } 136 var fan = ste[1].split(':'); 137 if (fan[0] == 'bootstrap.js') { 138 continue; 139 } 140 stack.push({ 141 arguments: ste[0], 142 fileName: fan[0], 143 lineNumber: fan[1] 144 }); 145 } 146 return stack; 147 } 148 }); 149 150