This document discusses handling errors in web applications. It begins by explaining what JavaScript errors are and how they are typically invisible to users. It then discusses how to catch errors using window.onerror or addEventListener and logging errors to help debug issues. Ideal error handling involves logging detailed error information to a database and notifying developers. The document wishes for more context around errors, like function arguments or AJAX requests. It introduces a new error logging and monitoring tool that provides detailed user environment data, function arguments, screenshots, and a timeline to help developers debug issues more easily.
Automating Google Workspace (GWS) & more with Apps Script
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
1. Expect the unexpected - dealing with
errors in web apps
Mats Bryntse
Founder, @bryntum
2. 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
4. 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 ?
7. 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
8. Global error handler
// Old school
window.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
9. You can throw your own
Error too
// Bad, no call stack will be available
throw ‘My own error’;
// preferred
throw 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
12. Flow of an error - Enterprise version
Error in web app
Reports to own support Your company
User realises it’s an error
01010
10110
11110
User Dear User,
/Depressed dev.
Can’t reproduce,
need more info.
Sincerely yours,
22. 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");
23. 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
24. Flow of an error - Improved version
Error in web app
Your company
User realises it’s an error
01010
10110
11110
User
30. 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
31. Error handling at Bryntum
Instant feedback
Site visitors / “Late QA”Developers
32. 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…
🕵🕵
34. 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
35. Logs about failed ajax requests
Usually produces errors that are less tested (aka happy testing)
36. See how the application looked at the time of
crash
?
45. + environment data collected
Many things to consider…
• OS
• Browser
• Window size
• Touch support
• Window blur/focus events
• Date + Timezone
• Language
• Failed ajax requests
• Cookie state
• Network connectivity events
52. 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');
53. 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
�