PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/ext/src/core/src/lang/Error.js

http://github.com/brunotavares/Ext.ux.Router
JavaScript | 329 lines | 100 code | 28 blank | 201 comment | 23 complexity | abde042a99e201412e4a26fd3cb620ab MD5 | raw file
  1. //@tag foundation,core
  2. //@require ../class/Loader.js
  3. /**
  4. * @author Brian Moeskau <brian@sencha.com>
  5. * @docauthor Brian Moeskau <brian@sencha.com>
  6. *
  7. * A wrapper class for the native JavaScript Error object that adds a few useful capabilities for handling
  8. * errors in an Ext application. When you use Ext.Error to {@link #raise} an error from within any class that
  9. * uses the Ext 4 class system, the Error class can automatically add the source class and method from which
  10. * the error was raised. It also includes logic to automatically log the error to the console, if available,
  11. * with additional metadata about the error. In all cases, the error will always be thrown at the end so that
  12. * execution will halt.
  13. *
  14. * Ext.Error also offers a global error {@link #handle handling} method that can be overridden in order to
  15. * handle application-wide errors in a single spot. You can optionally {@link #ignore} errors altogether,
  16. * although in a real application it's usually a better idea to override the handling function and perform
  17. * logging or some other method of reporting the errors in a way that is meaningful to the application.
  18. *
  19. * At its simplest you can simply raise an error as a simple string from within any code:
  20. *
  21. * Example usage:
  22. *
  23. * Ext.Error.raise('Something bad happened!');
  24. *
  25. * If raised from plain JavaScript code, the error will be logged to the console (if available) and the message
  26. * displayed. In most cases however you'll be raising errors from within a class, and it may often be useful to add
  27. * additional metadata about the error being raised. The {@link #raise} method can also take a config object.
  28. * In this form the `msg` attribute becomes the error description, and any other data added to the config gets
  29. * added to the error object and, if the console is available, logged to the console for inspection.
  30. *
  31. * Example usage:
  32. *
  33. * Ext.define('Ext.Foo', {
  34. * doSomething: function(option){
  35. * if (someCondition === false) {
  36. * Ext.Error.raise({
  37. * msg: 'You cannot do that!',
  38. * option: option, // whatever was passed into the method
  39. * 'error code': 100 // other arbitrary info
  40. * });
  41. * }
  42. * }
  43. * });
  44. *
  45. * If a console is available (that supports the `console.dir` function) you'll see console output like:
  46. *
  47. * An error was raised with the following data:
  48. * option: Object { foo: "bar"}
  49. * foo: "bar"
  50. * error code: 100
  51. * msg: "You cannot do that!"
  52. * sourceClass: "Ext.Foo"
  53. * sourceMethod: "doSomething"
  54. *
  55. * uncaught exception: You cannot do that!
  56. *
  57. * As you can see, the error will report exactly where it was raised and will include as much information as the
  58. * raising code can usefully provide.
  59. *
  60. * If you want to handle all application errors globally you can simply override the static {@link #handle} method
  61. * and provide whatever handling logic you need. If the method returns true then the error is considered handled
  62. * and will not be thrown to the browser. If anything but true is returned then the error will be thrown normally.
  63. *
  64. * Example usage:
  65. *
  66. * Ext.Error.handle = function(err) {
  67. * if (err.someProperty == 'NotReallyAnError') {
  68. * // maybe log something to the application here if applicable
  69. * return true;
  70. * }
  71. * // any non-true return value (including none) will cause the error to be thrown
  72. * }
  73. *
  74. */
  75. Ext.Error = Ext.extend(Error, {
  76. statics: {
  77. /**
  78. * @property {Boolean} ignore
  79. * Static flag that can be used to globally disable error reporting to the browser if set to true
  80. * (defaults to false). Note that if you ignore Ext errors it's likely that some other code may fail
  81. * and throw a native JavaScript error thereafter, so use with caution. In most cases it will probably
  82. * be preferable to supply a custom error {@link #handle handling} function instead.
  83. *
  84. * Example usage:
  85. *
  86. * Ext.Error.ignore = true;
  87. *
  88. * @static
  89. */
  90. ignore: false,
  91. /**
  92. * @property {Boolean} notify
  93. * Static flag that can be used to globally control error notification to the user. Unlike
  94. * Ex.Error.ignore, this does not effect exceptions. They are still thrown. This value can be
  95. * set to false to disable the alert notification (default is true for IE6 and IE7).
  96. *
  97. * Only the first error will generate an alert. Internally this flag is set to false when the
  98. * first error occurs prior to displaying the alert.
  99. *
  100. * This flag is not used in a release build.
  101. *
  102. * Example usage:
  103. *
  104. * Ext.Error.notify = false;
  105. *
  106. * @static
  107. */
  108. //notify: Ext.isIE6 || Ext.isIE7,
  109. /**
  110. * Raise an error that can include additional data and supports automatic console logging if available.
  111. * You can pass a string error message or an object with the `msg` attribute which will be used as the
  112. * error message. The object can contain any other name-value attributes (or objects) to be logged
  113. * along with the error.
  114. *
  115. * Note that after displaying the error message a JavaScript error will ultimately be thrown so that
  116. * execution will halt.
  117. *
  118. * Example usage:
  119. *
  120. * Ext.Error.raise('A simple string error message');
  121. *
  122. * // or...
  123. *
  124. * Ext.define('Ext.Foo', {
  125. * doSomething: function(option){
  126. * if (someCondition === false) {
  127. * Ext.Error.raise({
  128. * msg: 'You cannot do that!',
  129. * option: option, // whatever was passed into the method
  130. * 'error code': 100 // other arbitrary info
  131. * });
  132. * }
  133. * }
  134. * });
  135. *
  136. * @param {String/Object} err The error message string, or an object containing the attribute "msg" that will be
  137. * used as the error message. Any other data included in the object will also be logged to the browser console,
  138. * if available.
  139. * @static
  140. */
  141. raise: function(err){
  142. err = err || {};
  143. if (Ext.isString(err)) {
  144. err = { msg: err };
  145. }
  146. var method = this.raise.caller,
  147. msg;
  148. if (method) {
  149. if (method.$name) {
  150. err.sourceMethod = method.$name;
  151. }
  152. if (method.$owner) {
  153. err.sourceClass = method.$owner.$className;
  154. }
  155. }
  156. if (Ext.Error.handle(err) !== true) {
  157. msg = Ext.Error.prototype.toString.call(err);
  158. Ext.log({
  159. msg: msg,
  160. level: 'error',
  161. dump: err,
  162. stack: true
  163. });
  164. throw new Ext.Error(err);
  165. }
  166. },
  167. /**
  168. * Globally handle any Ext errors that may be raised, optionally providing custom logic to
  169. * handle different errors individually. Return true from the function to bypass throwing the
  170. * error to the browser, otherwise the error will be thrown and execution will halt.
  171. *
  172. * Example usage:
  173. *
  174. * Ext.Error.handle = function(err) {
  175. * if (err.someProperty == 'NotReallyAnError') {
  176. * // maybe log something to the application here if applicable
  177. * return true;
  178. * }
  179. * // any non-true return value (including none) will cause the error to be thrown
  180. * }
  181. *
  182. * @param {Ext.Error} err The Ext.Error object being raised. It will contain any attributes that were originally
  183. * raised with it, plus properties about the method and class from which the error originated (if raised from a
  184. * class that uses the Ext 4 class system).
  185. * @static
  186. */
  187. handle: function(){
  188. return Ext.Error.ignore;
  189. }
  190. },
  191. // This is the standard property that is the name of the constructor.
  192. name: 'Ext.Error',
  193. /**
  194. * Creates new Error object.
  195. * @param {String/Object} config The error message string, or an object containing the
  196. * attribute "msg" that will be used as the error message. Any other data included in
  197. * the object will be applied to the error instance and logged to the browser console, if available.
  198. */
  199. constructor: function(config){
  200. if (Ext.isString(config)) {
  201. config = { msg: config };
  202. }
  203. var me = this;
  204. Ext.apply(me, config);
  205. me.message = me.message || me.msg; // 'message' is standard ('msg' is non-standard)
  206. // note: the above does not work in old WebKit (me.message is readonly) (Safari 4)
  207. },
  208. /**
  209. * Provides a custom string representation of the error object. This is an override of the base JavaScript
  210. * `Object.toString` method, which is useful so that when logged to the browser console, an error object will
  211. * be displayed with a useful message instead of `[object Object]`, the default `toString` result.
  212. *
  213. * The default implementation will include the error message along with the raising class and method, if available,
  214. * but this can be overridden with a custom implementation either at the prototype level (for all errors) or on
  215. * a particular error instance, if you want to provide a custom description that will show up in the console.
  216. * @return {String} The error message. If raised from within the Ext 4 class system, the error message will also
  217. * include the raising class and method names, if available.
  218. */
  219. toString: function(){
  220. var me = this,
  221. className = me.sourceClass ? me.sourceClass : '',
  222. methodName = me.sourceMethod ? '.' + me.sourceMethod + '(): ' : '',
  223. msg = me.msg || '(No description provided)';
  224. return className + methodName + msg;
  225. }
  226. });
  227. /*
  228. * Create a function that will throw an error if called (in debug mode) with a message that
  229. * indicates the method has been removed.
  230. * @param {String} suggestion Optional text to include in the message (a workaround perhaps).
  231. * @return {Function} The generated function.
  232. * @private
  233. */
  234. Ext.deprecated = function (suggestion) {
  235. //<debug>
  236. if (!suggestion) {
  237. suggestion = '';
  238. }
  239. function fail () {
  240. Ext.Error.raise('The method "' + fail.$owner.$className + '.' + fail.$name +
  241. '" has been removed. ' + suggestion);
  242. }
  243. return fail;
  244. //</debug>
  245. return Ext.emptyFn;
  246. };
  247. /*
  248. * This mechanism is used to notify the user of the first error encountered on the page. This
  249. * was previously internal to Ext.Error.raise and is a desirable feature since errors often
  250. * slip silently under the radar. It cannot live in Ext.Error.raise since there are times
  251. * where exceptions are handled in a try/catch.
  252. */
  253. //<debug>
  254. (function () {
  255. var timer, errors = 0,
  256. win = Ext.global,
  257. msg;
  258. if (typeof window === 'undefined') {
  259. return; // build system or some such environment...
  260. }
  261. // This method is called to notify the user of the current error status.
  262. function notify () {
  263. var counters = Ext.log.counters,
  264. supports = Ext.supports,
  265. hasOnError = supports && supports.WindowOnError; // TODO - timing
  266. // Put log counters to the status bar (for most browsers):
  267. if (counters && (counters.error + counters.warn + counters.info + counters.log)) {
  268. msg = [ 'Logged Errors:',counters.error, 'Warnings:',counters.warn,
  269. 'Info:',counters.info, 'Log:',counters.log].join(' ');
  270. if (errors) {
  271. msg = '*** Errors: ' + errors + ' - ' + msg;
  272. } else if (counters.error) {
  273. msg = '*** ' + msg;
  274. }
  275. win.status = msg;
  276. }
  277. // Display an alert on the first error:
  278. if (!Ext.isDefined(Ext.Error.notify)) {
  279. Ext.Error.notify = Ext.isIE6 || Ext.isIE7; // TODO - timing
  280. }
  281. if (Ext.Error.notify && (hasOnError ? errors : (counters && counters.error))) {
  282. Ext.Error.notify = false;
  283. if (timer) {
  284. win.clearInterval(timer); // ticks can queue up so stop...
  285. timer = null;
  286. }
  287. alert('Unhandled error on page: See console or log');
  288. poll();
  289. }
  290. }
  291. // Sets up polling loop. This is the only way to know about errors in some browsers
  292. // (Opera/Safari) and is the only way to update the status bar for warnings and other
  293. // non-errors.
  294. function poll () {
  295. timer = win.setInterval(notify, 1000);
  296. }
  297. // window.onerror sounds ideal but it prevents the built-in error dialog from doing
  298. // its (better) thing.
  299. poll();
  300. }());
  301. //</debug>