lightning talk: javascript error handling

25
JavaScript Error Handling Nick Burwell Principal UX Engineer Invoca, Inc.

Upload: nick-burwell

Post on 13-Apr-2017

598 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Lightning Talk: JavaScript Error Handling

JavaScript Error HandlingNick BurwellPrincipal UX EngineerInvoca, Inc.

Page 2: Lightning Talk: JavaScript Error Handling

Why are JavaScript errors so scary?

Page 3: Lightning Talk: JavaScript Error Handling

Why are JavaScript errors so prominent?

Page 4: Lightning Talk: JavaScript Error Handling

Why are JavaScript errors so often ignored?

Page 5: Lightning Talk: JavaScript Error Handling

A few thoughts...Dynamic language, weakly-typed

Intersection of JS and HTML/DOM

Browser differences

Often lack of test coverage

Assets missing / order dependencies

Spotty networks, load errors

Page 6: Lightning Talk: JavaScript Error Handling

Do your developers & QA notice errors locally?

How easy are they to debug once they occur?

Do you know about errors that happen in production?

Page 7: Lightning Talk: JavaScript Error Handling

So how do we do better?CC: https://www.flickr.com/photos/verpletterend/5393470920

Page 8: Lightning Talk: JavaScript Error Handling

Do your developers & QA notice errors locally?

Components should enforce their contractRaise errors when not met

Don't just silently failProvide useful context to debug

Page 9: Lightning Talk: JavaScript Error Handling

Example from DataTables

Page 10: Lightning Talk: JavaScript Error Handling

Example from React componentsReact = require('react');

var Button = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired }, ...});

Page 11: Lightning Talk: JavaScript Error Handling

Basic Error Handlingfunction foo() { if (typeof title === "undefined") { throw new Error("title should be defined"); }}

try { foo();} catch (ex){ // handle error}

Page 12: Lightning Talk: JavaScript Error Handling

Error Hierarchy

Error

EvalError RangeError ReferenceError SyntaxError TypeError URIError

Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

Page 13: Lightning Talk: JavaScript Error Handling

Define your own Errorfunction NotFoundError(message){ this.message = message;}

NotFoundError.prototype = new Error();

...

throw new NotFoundError("Could not find ID: foobar");

source

Surprising results!No stack, no error name

Page 14: Lightning Talk: JavaScript Error Handling

Define your own Errorfunction NotFoundError(message){ this.name = "NotFoundError"; this.message = message; this.stack = (new Error()).stack;}

NotFoundError.prototype = Object.create(Error.prototype);NotFoundError.prototype.constructor = NotFoundError;

...

throw new NotFoundError("Could not find ID: foobar");

< 8

Page 15: Lightning Talk: JavaScript Error Handling

Have an easy way to log errorsSimple interface

Adapt based on whether in dev or production

Show error prominently in dev!

Send to exception monitoring in production

Page 16: Lightning Talk: JavaScript Error Handling

Don't catch simply to log to consoleDon't simply log to console as the way to "handle" errors

try { // something that causes an error} catch (ex){ console.log("ERROR: " + ex.message + "\n" + ex.stack);}

Antipattern!

Page 17: Lightning Talk: JavaScript Error Handling
Page 18: Lightning Talk: JavaScript Error Handling
Page 19: Lightning Talk: JavaScript Error Handling

Expect the unexpectedvar status = this.model.get('status');switch (status) { case 'active': // do something here... break; case 'paused': // do something else here... break; case 'archived': // do different stuff here... break; default: Invoca.logError("No status handling for value: " + status, context);}

Page 20: Lightning Talk: JavaScript Error Handling

Catch and report ALL the errors!window.onerror = function( message, scriptUrl, lineNumber, characterNumber, error) {

// handle error! Notifier.log(message, error.stack);

// return true; prevents default browser handling}

Now supported by all modern browsers (even IE!) … except Safari

Page 21: Lightning Talk: JavaScript Error Handling

Before...You couldn't get a stack from window.onerror errors

Two common strategies to work around were:

Rely on onerror anyway

In production mode have a much harder problem debugging issues

Put try/catch's around all your code

Difficult to ensure around all event handlers, timers, ajax callbacks

If exception is caught in development, harder to use browser tools to debug

Middle ground: dynamically wrap with try/catch in production only

Page 22: Lightning Talk: JavaScript Error Handling

Now...Use window.onerror

Consider also using a library to wrap events / callbacks

In production, log errors to your error monitoring server

Invoca combines JS errors with our Rails / other ruby errors

Includes user / session / browser / URL data

3rd party solutions available

Bugsnag

Rollbar

In development, let unexpected errors bubble up / rely on browser tools

Page 23: Lightning Talk: JavaScript Error Handling

Minification & obfuscationEven a message & stack doesn't mean you can decipher uncaught errors

Solution: allow your sourcemap files to be accessible

developers can unobfuscate and make sense of errors

Ensure sourcemaps are enabled in your minifying / concatenating of assets

Rails asset pipeline doesn't provide out of box (fix with precompile task)

Node based options usually have config options for sourcemaps

Page 24: Lightning Talk: JavaScript Error Handling

A full development cycle strategyMake components easy to integrate with in development

Make things easy to debug in development & testing (when errors happen)

Report unexpected errors to a logging / monitoring system in production

Don't expose ugly exceptions to users in production

Page 25: Lightning Talk: JavaScript Error Handling

ResourcesPre-built logging & monitoring tools

Bugsnag: Product | JS logging repo

Rollbar: Product | JS logging repo

New Relic: Product

Log4JavaScript: Docs

Articles on JS errors

https://bugsnag.com/blog/js-stacktraces

https://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

https://www.nczonline.net/blog/2009/04/28/javascript-error-handling-anti-pattern/

Thanks!