1/***************************************************************************** 2 * 3 * Copyright (c) 2004-2007 Guido Wesdorp. All rights reserved. 4 * 5 * This software is distributed under the terms of the JSBase 6 * License. See LICENSE.txt for license text. 7 * 8 *****************************************************************************/ 9 10var global = this; 11global.exception = new function() { 12 /* Exception handling in a somewhat coherent manner */ 13 14 var exception = this; 15 16 this.Exception = function(message) { 17 /* base class of exceptions */ 18 if (message !== undefined) { 19 this._initialize('Exception', message); 20 }; 21 }; 22 23 this.Exception.prototype._initialize = function(name, message) { 24 this.name = name; 25 this.message = message; 26 var stack = this.stack = exception._createStack(); 27 this.lineNo = exception._getLineNo(stack); 28 this.fileName = exception._getFileName(stack); 29 }; 30 31 this.Exception.prototype.toString = function() { 32 var lineNo = this.lineNo; 33 var fileName = this.fileName; 34 var stack = this.stack; 35 var exc = this.name + ': ' + this.message + '\n'; 36 if (lineNo || fileName || stack) { 37 exc += '\n'; 38 }; 39 if (fileName) { 40 exc += 'file: ' + fileName; 41 if (lineNo) { 42 exc += ', '; 43 } else { 44 exc += '\n'; 45 }; 46 }; 47 if (lineNo) { 48 exc += 'line: ' + lineNo + '\n'; 49 }; 50 if (stack) { 51 exc += '\n'; 52 var lines = stack.split('\n'); 53 for (var i=0; i < lines.length; i++) { 54 var line = lines[i]; 55 if (line.charAt(0) == '(') { 56 line = 'function' + line; 57 }; 58 exc += line + '\n'; 59 }; 60 }; 61 return exc; 62 }; 63 64 this.ValueError = function(message) { 65 /* raised on providing invalid values */ 66 if (message !== undefined) { 67 this._initialize('ValueError', message); 68 }; 69 }; 70 71 this.ValueError.prototype = new this.Exception; 72 73 this.AssertionError = function(message) { 74 /* raised when an assertion fails */ 75 if (message !== undefined) { 76 this._initialize('AssertionError', message); 77 }; 78 }; 79 80 this.AssertionError.prototype = new this.Exception; 81 82 // XXX need to define a load of useful exceptions here 83 this.NotSupported = function(message) { 84 /* raised when a feature is not supported on the running platform */ 85 if (message !== undefined) { 86 this._initialize('NotSupported', message); 87 }; 88 }; 89 90 this.NotSupported.prototype = new this.Exception; 91 92 this.NotFound = function(message) { 93 /* raised when something is not found */ 94 if (message !== undefined) { 95 this._initialize('NotFound', message); 96 }; 97 }; 98 99 this.NotFound.prototype = new this.Exception; 100 101 this.HTTPError = function(status) { 102 if (status !== undefined) { 103 // XXX need to get the message for the error here... 104 this._initialize('HTTPError', status); 105 }; 106 }; 107 108 this.HTTPError.prototype = new this.Exception; 109 110 this.MissingDependency = function(missing, from) { 111 /* raised when some dependency can not be resolved */ 112 if (missing !== undefined) { 113 var message = missing; 114 if (from) { 115 message += ' (from ' + from + ')'; 116 }; 117 this._initialize('MissingDependency', message); 118 }; 119 }; 120 121 this.NotFound.prototype = new this.Exception; 122 123 this._createStack = function() { 124 /* somewhat nasty trick to get a stack trace in (works only in Moz) */ 125 var stack = undefined; 126 try {notdefined()} catch(e) {stack = e.stack}; 127 if (stack) { 128 stack = stack.split('\n'); 129 stack.shift(); 130 stack.shift(); 131 }; 132 return stack ? stack.join('\n') : ''; 133 }; 134 135 this._getLineNo = function(stack) { 136 /* tries to get the line no in (works only in Moz) */ 137 if (!stack) { 138 return; 139 }; 140 stack = stack.toString().split('\n'); 141 var chunks = stack[0].split(':'); 142 var lineno = chunks[chunks.length - 1]; 143 if (lineno != '0') { 144 return lineno; 145 }; 146 }; 147 148 this._getFileName = function(stack) { 149 /* tries to get the filename in (works only in Moz) */ 150 if (!stack) { 151 return; 152 }; 153 stack = stack.toString().split('\n'); 154 var chunks = stack[0].split(':'); 155 var filename = chunks[chunks.length - 2]; 156 return filename; 157 }; 158}(); 159