1. #1
    Sencha - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,810
    Vote Rating
    133
    mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold

      13  

    Default Basic error handling for Ext JS apps

    Basic error handling for Ext JS apps


    A small useful snippet that we use (at Bryntum) for logging errors in our Ext JS apps. Thought it might be useful for other devs in the Sencha community.

    Code:
    Ext.define("CZ.util.ErrorLogger", {
        singleton       : true,
        logUrl          : 'http://your.domain.com/log.php',
        // Log only one error per page visit
        maxNbrLogs      : 1,
        nbrErrorsLogged : 0,
    
        constructor : function () {
            window.onerror = Ext.Function.bind(this.onError, this);
        },
    
        onError : function (message, file, line, column, errorObj) {
            var win = window,
                d = document;
    
            if (!message || message.match('chrome://') || message.match('Script error')) {
                return;
            }
    
            if (this.nbrErrorsLogged < this.maxNbrLogs && message && (line || file)) {
                this.nbrErrorsLogged++;
    
                var windowWidth = win.innerWidth || d.documentElement.clientWidth || d.body.clientWidth,
                    windowHeight = win.innerHeight || d.documentElement.clientHeight || d.body.clientHeight;
    
                var crashData = {
                    msg          : message,
                    url          : file,
                    line         : line,
                    href         : win.location.href,
                    windowWidth  : windowWidth,
                    windowHeight : windowHeight,
                    extVersion   : Ext.versions && Ext.versions.extjs && Ext.versions.extjs.version,
                    localDate    : new Date().toString(),
    
                    browser : (Ext.ieVersion && "IE" + Ext.ieVersion) ||
                    (Ext.chromeVersion && "Chrome" + Ext.chromeVersion) ||
                    (Ext.firefoxVersion && "FF" + Ext.firefoxVersion) ||
                    (Ext.safariVersion && "Safari" + Ext.safariVersion) ||
                    (Ext.operaVersion && "Opera" + Ext.operaVersion) ||
                    navigator.userAgent,
    
                    column : column || '',
                    stack  : (errorObj && errorObj.stack) || ''
                };
    
                var crashString = '';
    
                Ext.Object.each(crashData, function (key, value) {
                    crashString += (key + '=' + encodeURIComponent(value) + '&');
                });
    
                new Image().src = this.logUrl + '?' + crashString;
            }
        }
    });

  2. #2
    Ext JS Premium Member
    Join Date
    May 2008
    Posts
    190
    Vote Rating
    63
    sg707 is a jewel in the rough sg707 is a jewel in the rough sg707 is a jewel in the rough

      0  

    Default


    Very cool! does that new Image gets cleaned up after sending the data? I'm guessing you need to invoke destroy().

  3. #3
    Sencha Premium Member Zdeno's Avatar
    Join Date
    Nov 2009
    Location
    Prague
    Posts
    558
    Vote Rating
    36
    Zdeno has a spectacular aura about Zdeno has a spectacular aura about

      0  

    Default


    Excellent Mats. Love you for this solution !!!

  4. #4
    Sencha - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,810
    Vote Rating
    133
    mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold

      1  

    Default


    @sg707: Nothing to clean up (img never gets added to the DOM).

    @zdeno: Happy to help

  5. #5
    Sencha - Support Team
    Join Date
    Feb 2013
    Location
    California
    Posts
    4,082
    Vote Rating
    69
    Gary Schlosberg has a spectacular aura about Gary Schlosberg has a spectacular aura about Gary Schlosberg has a spectacular aura about

      0  

    Default


    Cool bit of code. Thanks for sharing!


    Are you a Sencha products veteran who has wondered what it might be like to work at Sencha? If so, please reach out to our recruiting manager:
    sheryl@sencha.com

  6. #6
    Touch Premium Member
    Join Date
    Sep 2011
    Location
    Tamworth, NSW, Australia
    Posts
    667
    Vote Rating
    111
    marc.fearby is just really nice marc.fearby is just really nice marc.fearby is just really nice marc.fearby is just really nice marc.fearby is just really nice

      0  

    Default


    So I'm guessing that Image().src is a sneaky way of firing off a request (with query string data in this case) to the server without doing an ajax request or anything else? Nice.

  7. #7

  8. #8
    Sencha User
    Join Date
    Nov 2014
    Posts
    3
    Vote Rating
    0
    DomusDevs is on a distinguished road

      0  

    Default


    Thanks for sharing Mats. Last link you provided have raised an idea:

    Assuming we have the ability to track (server side) both errors and user actions within apps, wouldn't be nice to be able to:
    1. Get info from server (email/instant msg) when a critical error occurred
    2. Be able to "replay" what the user have done, in debug mode (all msgs fired on screen), to speed up bug fixing

    Don't know if tools like Siesta can be somehow useful to accomplish that.

  9. #9
    Sencha - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,810
    Vote Rating
    133
    mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold

      3  

    Default


    This is exactly what we do. We record interactions in our online samples http://bryntum.com/examples/ and if there's a crash we generate a simple Siesta test case that we can immediately play back and investigate. This is a sample crash dump we email to our devs:

    Code:
    Message: Uncaught TypeError: Cannot read property 'id' of null 
    
    Url: http://www.bryntum.com/examples/taskboard-latest/examples/advanced/ 
    
    Line: 1 
    
    Href: http://www.bryntum.com/examples/taskboard-latest/examples/advanced/
    
    Browser: Chrome39
    
    Product version: 2.0.0
    
    Local date: Fri Dec 12 2014 17:01:25 GMT+0800 (中国标准时间)
    
    Window size: 1366 x 621 
    
    Column: 69 
    
    Stack: TypeError: Cannot read property 'id' of null
       at Ext.define.resolveViewByNode (eval at <anonymous> (http://www.bryntum.com/examples/taskboard-latest/taskboard-all-debug.js:10:145894), <anonymous>:1:46667)
       at Ext.define.resolveRecordByNode (eval at <anonymous> (http://www.bryntum.com/examples/taskboard-latest/taskboard-all-debug.js:10:145894), <anonymous>:1:46720)
       at Ext.define.getDragData (eval at <anonymous> (http://www.bryntum.com/examples/taskboard-latest/taskboard-all-debug.js:10:145894), <anonymous>:1:25717)
       at Ext.cmd.derive.handleMouseDown (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:1048052)
       at Ext.cmd.derive.doFire (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:133535)
       at Ext.cmd.derive.fire (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:132474)
       at Ext.cmd.derive.doDispatchEvent (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:139149)
       at Ext.cmd.derive.dispatch (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:439002)
       at Ext.cmd.derive.dispatch (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:457642)
       at Ext.cmd.derive.doPublish (http://cdn.sencha.com/ext/gpl/5.0.1/build/ext-all.js:22:458541)
    
    Clicks: [{"desc":"click \"#filterfield-1031-inputEl\"","click":[126,12]},{"desc":"click \"#highlightfield-1033-inputEl\"","click":[429,17]},{"desc":"click \"#columnfilter-1035-trigger-picker\"","click":[767,23]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[732,52]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[729,80]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[704,108]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[704,144]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[677,173]},{"desc":"click \"#columnfilter-1035-trigger-picker\"","click":[760,19]},{"desc":"click \"#columnfilter-1035-trigger-picker\"","click":[761,18]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[632,47]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[643,78]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[644,106
    ]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[642,140]},{"desc":"click \"#boundlist-1036-listEl .x-boundlist-item\"","click":[640,163]},{"desc":"click \"#toolbar-1029-innerCt\"","click":[838,25]},{"desc":"click \"#ext-element-3 .sch-task-inner\"","click":[172,269]},{"desc":"click \"#ext-element-3 .sch-task-inner .sch-tool-ct .sch-tool.sch-tool-edit\"","click":[60,288]}]

  10. #10
    Ext JS Premium Member
    Join Date
    Sep 2011
    Posts
    27
    Vote Rating
    0
    dmurat is on a distinguished road

      0  

    Default


    @mankz Can you, please, elaborate a bit more on this client tracking and automated siesta test generation? Maybe with some code examples?

    If not, did you maybe considered to offer your solution as a commercial product. I believe many would be interested :-)