3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
20 A wrapper class for the native JavaScript Error object that adds a few useful capabilities for handling
21 errors in an Ext application. When you use Ext.Error to {@link #raise} an error from within any class that
22 uses the Ext 4 class system, the Error class can automatically add the source class and method from which
23 the error was raised. It also includes logic to automatically log the eroor to the console, if available,
24 with additional metadata about the error. In all cases, the error will always be thrown at the end so that
27 Ext.Error also offers a global error {@link #handle handling} method that can be overridden in order to
28 handle application-wide errors in a single spot. You can optionally {@link #ignore} errors altogether,
29 although in a real application it's usually a better idea to override the handling function and perform
30 logging or some other method of reporting the errors in a way that is meaningful to the application.
32 At its simplest you can simply raise an error as a simple string from within any code:
36 Ext.Error.raise('Something bad happened!');
38 If raised from plain JavaScript code, the error will be logged to the console (if available) and the message
39 displayed. In most cases however you'll be raising errors from within a class, and it may often be useful to add
40 additional metadata about the error being raised. The {@link #raise} method can also take a config object.
41 In this form the `msg` attribute becomes the error description, and any other data added to the config gets
42 added to the error object and, if the console is available, logged to the console for inspection.
46 Ext.define('Ext.Foo', {
47 doSomething: function(option){
48 if (someCondition === false) {
50 msg: 'You cannot do that!',
51 option: option, // whatever was passed into the method
52 'error code': 100 // other arbitrary info
58 If a console is available (that supports the `console.dir` function) you'll see console output like:
60 An error was raised with the following data:
61 option: Object { foo: "bar"}
64 msg: "You cannot do that!"
65 sourceClass: "Ext.Foo"
66 sourceMethod: "doSomething"
68 uncaught exception: You cannot do that!
70 As you can see, the error will report exactly where it was raised and will include as much information as the
71 raising code can usefully provide.
73 If you want to handle all application errors globally you can simply override the static {@link #handle} method
74 and provide whatever handling logic you need. If the method returns true then the error is considered handled
75 and will not be thrown to the browser. If anything but true is returned then the error will be thrown normally.
79 Ext.Error.handle = function(err) {
80 if (err.someProperty == 'NotReallyAnError') {
81 // maybe log something to the application here if applicable
84 // any non-true return value (including none) will cause the error to be thrown
87 * Create a new Error object
88 * @param {Object} config The config object
90 * @author Brian Moeskau <brian@sencha.com>
91 * @docauthor Brian Moeskau <brian@sencha.com>
93 Ext.Error = Ext.extend(Error, {
97 Static flag that can be used to globally disable error reporting to the browser if set to true
98 (defaults to false). Note that if you ignore Ext errors it's likely that some other code may fail
99 and throw a native JavaScript error thereafter, so use with caution. In most cases it will probably
100 be preferable to supply a custom error {@link #handle handling} function instead.
104 Ext.Error.ignore = true;
113 Static flag that can be used to globally control error notification to the user. Unlike
114 Ex.Error.ignore, this does not effect exceptions. They are still thrown. This value can be
115 set to false to disable the alert notification (default is true for IE6 and IE7).
117 Only the first error will generate an alert. Internally this flag is set to false when the
118 first error occurs prior to displaying the alert.
120 This flag is not used in a release build.
124 Ext.Error.notify = false;
129 //notify: Ext.isIE6 || Ext.isIE7,
132 Raise an error that can include additional data and supports automatic console logging if available.
133 You can pass a string error message or an object with the `msg` attribute which will be used as the
134 error message. The object can contain any other name-value attributes (or objects) to be logged
135 along with the error.
137 Note that after displaying the error message a JavaScript error will ultimately be thrown so that
142 Ext.Error.raise('A simple string error message');
146 Ext.define('Ext.Foo', {
147 doSomething: function(option){
148 if (someCondition === false) {
150 msg: 'You cannot do that!',
151 option: option, // whatever was passed into the method
152 'error code': 100 // other arbitrary info
157 * @param {String/Object} err The error message string, or an object containing the
158 * attribute "msg" that will be used as the error message. Any other data included in
159 * the object will also be logged to the browser console, if available.
163 raise: function(err){
165 if (Ext.isString(err)) {
169 var method = this.raise.caller;
173 err.sourceMethod = method.$name;
176 err.sourceClass = method.$owner.$className;
180 if (Ext.Error.handle(err) !== true) {
181 var msg = Ext.Error.prototype.toString.call(err);
190 throw new Ext.Error(err);
195 Globally handle any Ext errors that may be raised, optionally providing custom logic to
196 handle different errors individually. Return true from the function to bypass throwing the
197 error to the browser, otherwise the error will be thrown and execution will halt.
201 Ext.Error.handle = function(err) {
202 if (err.someProperty == 'NotReallyAnError') {
203 // maybe log something to the application here if applicable
206 // any non-true return value (including none) will cause the error to be thrown
209 * @param {Ext.Error} err The Ext.Error object being raised. It will contain any attributes
210 * that were originally raised with it, plus properties about the method and class from which
211 * the error originated (if raised from a class that uses the Ext 4 class system).
216 return Ext.Error.ignore;
220 // This is the standard property that is the name of the constructor.
224 * @param {String/Object} config The error message string, or an object containing the
225 * attribute "msg" that will be used as the error message. Any other data included in
226 * the object will be applied to the error instance and logged to the browser console, if available.
228 constructor: function(config){
229 if (Ext.isString(config)) {
230 config = { msg: config };
235 Ext.apply(me, config);
237 me.message = me.message || me.msg; // 'message' is standard ('msg' is non-standard)
238 // note: the above does not work in old WebKit (me.message is readonly) (Safari 4)
242 Provides a custom string representation of the error object. This is an override of the base JavaScript
243 `Object.toString` method, which is useful so that when logged to the browser console, an error object will
244 be displayed with a useful message instead of `[object Object]`, the default `toString` result.
246 The default implementation will include the error message along with the raising class and method, if available,
247 but this can be overridden with a custom implementation either at the prototype level (for all errors) or on
248 a particular error instance, if you want to provide a custom description that will show up in the console.
250 * @return {String} The error message. If raised from within the Ext 4 class system, the error message
251 * will also include the raising class and method names, if available.
253 toString: function(){
255 className = me.className ? me.className : '',
256 methodName = me.methodName ? '.' + me.methodName + '(): ' : '',
257 msg = me.msg || '(No description provided)';
259 return className + methodName + msg;
264 * This mechanism is used to notify the user of the first error encountered on the page. This
265 * was previously internal to Ext.Error.raise and is a desirable feature since errors often
266 * slip silently under the radar. It cannot live in Ext.Error.raise since there are times
267 * where exceptions are handled in a try/catch.
271 var prevOnError, timer, errors = 0,
272 extraordinarilyBad = /(out of stack)|(too much recursion)|(stack overflow)|(out of memory)/i,
275 if (typeof window === 'undefined') {
276 return; // build system or some such environment...
279 // This method is called to notify the user of the current error status.
281 var counters = Ext.log.counters,
282 supports = Ext.supports,
283 hasOnError = supports && supports.WindowOnError; // TODO - timing
285 // Put log counters to the status bar (for most browsers):
286 if (counters && (counters.error + counters.warn + counters.info + counters.log)) {
287 var msg = [ 'Logged Errors:',counters.error, 'Warnings:',counters.warn,
288 'Info:',counters.info, 'Log:',counters.log].join(' ');
290 msg = '*** Errors: ' + errors + ' - ' + msg;
291 } else if (counters.error) {
297 // Display an alert on the first error:
298 if (!Ext.isDefined(Ext.Error.notify)) {
299 Ext.Error.notify = Ext.isIE6 || Ext.isIE7; // TODO - timing
301 if (Ext.Error.notify && (hasOnError ? errors : (counters && counters.error))) {
302 Ext.Error.notify = false;
305 win.clearInterval(timer); // ticks can queue up so stop...
309 alert('Unhandled error on page: See console or log');
314 // Sets up polling loop. This is the only way to know about errors in some browsers
315 // (Opera/Safari) and is the only way to update the status bar for warnings and other
318 timer = win.setInterval(notify, 1000);
321 // window.onerror is ideal (esp in IE) because you get full context. This is harmless
322 // otherwise (never called) which is good because you cannot feature detect it.
323 prevOnError = win.onerror || Ext.emptyFn;
324 win.onerror = function (message) {
327 if (!extraordinarilyBad.test(message)) {
328 // too much recursion + our alert right now = crash IE
329 // our polling loop will pick it up even if we don't alert now
333 return prevOnError.apply(this, arguments);