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