SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

57
Expect the unexpected - dealing with errors in web apps Mats Bryntse Founder, @bryntum

Transcript of SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Page 1: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Expect the unexpected - dealing with errors in web apps

Mats Bryntse

Founder, @bryntum

Page 2: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Who is Mats Bryntse?

• From Stockholm, Sweden

• Working with Ext JS since 2007

• mankz in the Sencha forums

• Founder of Bryntum (Scheduler, Gantt, Kanban Taskboard, Siesta)

• @bryntum

Page 3: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

What is a javascript Error?

Page 4: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Javascript error basics

• Javascript errors are unhandled exceptions happening in your code base

• Or in the frameworks you use

• Doesn’t matter where it happens, poor user impression regardless

• With JS codebases in the size of MBs, we can no longer ignore error handling + logging

• Good news - it’s easy 😀

Page 5: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

What does the user see when there is a JS error?

🤔

Page 6: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Nothing, unless you show them

😳

Page 7: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

The ErrorEvent constructor

• When an error happens, an ErrorEvent is fired on the window object

• ErrorEvent.message

• ErrorEvent.filename

• ErrorEvent.lineno

• ErrorEvent.colno // Normal browsers only

• ErrorEvent.error // Normal browsers only

Page 8: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Global error handler

// Old schoolwindow.onerror = function(message, source, lineno, colno, error) { … };

window.addEventListener(‘error’, function(event) { // event.message // event.filename // event.lineno // event.colno // good browsers only // event.error (has stack property, in good browsers)}, true);

…or by listening to the window ‘error’ eventListen with capture=true to also get notified of resource load errors

Errors are easily caught in window.onerror

Page 9: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

You can throw your own Error too

// Bad, no call stack will be availablethrow ‘My own error’;

// preferredthrow new Error(‘This will have call stack’);

try { // Questionable code goes here} catch(e) { // log error} finally { // always called}

• throw a String

• Or better, an Error instance (callstack)

• Catch using simple try/catch/finally

Page 10: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

The error reporting cycle

Page 11: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

What’s the typical strategy for error reporting at Enterprise X?

Page 12: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Flow of an error - Enterprise version

Error in web app

Reports to own support Your company

User realises it’s an error

010101011011110

User Dear User,

/Depressed dev.

Can’t reproduce, need more info.

Sincerely yours,

Page 13: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Too much guessing…

🕵🏼

Page 14: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

10 points

“Add-to-cart button doesn’t work”

Page 15: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

9 points ‘a is undefined’

Page 16: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

9 points ‘console.lgo is not a function’

Page 17: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

8 points line 1, column 536171

Page 18: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

7 points

Page 19: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

6 points

Page 20: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

5 points Step by step:First login as userAdd few items to cartClick checkout button => crash

Page 21: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Logging and monitoring errors in your web app

Page 22: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Logging is easy

• Log message, file, line, stack etc..

• Add any extra meta relevant for your debugging (userId/name/…)

• Poor mans error logger:

function log(msg) { new Image().src = "log.php?msg=" + encodeURIComponent(msg);}

window.onerror = log;

throw new Error("Ooops");

Page 23: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Saving error info

• Store error logs in some database on a non-production server

• Throttle logging on client side + server side

• Probably we only care about the first error on a page

Page 24: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Flow of an error - Improved version

Error in web app

Your company

User realises it’s an error

010101011011110

User

Page 25: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Making sense of a callstack is sometimes easy…

Page 26: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

…but often it takes a lot of detective work

🕵🏼

Page 27: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Solving a complex puzzleConnecting the dots…

undefined is not a function

Page 28: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Bryntum - How we (used to) handle errors

Page 29: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Online examples is a test suite of sorts

Page 30: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Previous error handling at Bryntum

• Web site visitors are test monkeys unknowingly === free help• Errors logged in a DB

• Emails sent to devs

= Very useful for finding and rapidly fixing bugs

Page 31: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Error handling at Bryntum

Instant feedback

Site visitors / “Late QA”Developers

Page 32: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Error handling at Bryntum

• What we had was pretty good, not great

• Lots of time spent playing detective, looking at callstacks

• Just error message, filename, callstack isn’t enough to rapidly locate root cause

• We would like to know more…

🕵🏼

Page 33: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Wish list…

Page 34: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Function arguments

Know how the crashing function was called

function getUserInfo(id) { var user = this.store.getById(id); // => null

return user.getInfo(); // Cannot call getInfo of null }

getUserInfo(-1); // crashes, would be neat to know input args

Page 35: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Logs about failed ajax requests

Usually produces errors that are less tested (aka happy testing)

Page 36: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

See how the application looked at the time of crash

?

Page 37: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Know what the user did during page session

🎥

Page 38: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

What if there was a tool that did all this…?

🤔😀

Page 39: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Introducing the new shiny…

Page 40: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
Page 41: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Detailed data about users environment

Page 42: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Capturing arguments passed to the crashing function

Page 43: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Screenshot at the time of the error

Page 44: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Support for hiding sensitive data before screenshot

Page 45: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

+ environment data collectedMany things to consider…

• OS

• Browser

• Window size

• Touch support

• Window blur/focus events

• Date + Timezone

• Language

• Failed ajax requests

• Cookie state

• Network connectivity events

Page 46: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Timeline visualising activityShows ajax requests, window resizing, hide/show, connectivity

Page 47: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Notifying the developers

Page 48: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Notifying the affected user

• Optional popup for the user that triggered the error

• Shows status of the error (New, Reproduced, Fixed)

Page 49: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Two way communication

Error data posted

Current error status [new/reproduced/fixed]

Users / QADevelopers

Page 50: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Cuts 99% of communication out

• No need for QA to email devs about crash reports

• No need for devs to notify QA that bug is already fixed

Page 51: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

DEMO TIME

Page 52: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Installing the logger in your app

var logger = new Err.ErrorLogger({ recordUserActions : true, maxNbrLogs : 1, logResourceLoadFailures : true, applicationId : ‘your-cool-app‘, version : ‘2.0.0-rc.1’, logAjaxRequests : true, enableScreenshot : true, saveCookies : true, frameworkVersion : Ext.versions.extjs.version });

logger.addTag('ReadOnlyUser', true); logger.addTag('Secret Flag', 'XYZ');

Page 53: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

In a dream world we would be able to:

See on the user’s machine when error happens live Reproduce the error on in production Reproduce the error locally

🤔

Page 54: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

DEMO TIME

Page 55: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

BETA release imminent

Beta testers wanted! [email protected]

Launch December 2016

Summing up:

Page 56: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps

Questions?

Page 57: SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps