PageRenderTime 28ms CodeModel.GetById 13ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Framework/ext-4.0.7/src/core/src/lang/Error.js

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