Mon Jul 31 2017

How can you tell the difference between a website written by a front end developer and a website written by a full stack developer? Look at the JavaScript logs in the console. If it's full of exceptions, warnings, or log statements, it says a lot about the coder. To a front end developer who takes pride in her job, shipping code that causes errors or debug statements to appear in the console is like trying to sell a car with the check engine light on.

A word on types

If you're working on a huge enterprise codebase and you have a lot of CS grads or Java devs contributing to front end code (I'm looking at you Amazon), these tips aren't really going to work. To put it in broad and overly-divisive terms, these folks live and die by their compilers. If it compiles and the use of whitespace was approved during code review, then it'll get shipped. For this crowd I recommend TypeScript or Flow or whatever. The nimble, artistic joy of dynamic typing is best suited to, well, nimble artists.

Now that I've enraged half the room, let's get started:

#1: Pause On Exceptions

Turn on the dark theme in Chrome's dev tools to arouse the envy of your neighbors.

In Chrome, open your developer tools, go to the Sources tab, and click on the little pause icon towards the right side. Now, while you are browsing with the developer tools open, Chrome will pause JavaScript execution whenever there is an uncaught exception, as if you had set a breakpoint at the offending line. You can then check out all the variables in that scope and start debugging immediately.

This is hugely helpful, not just because it saves you from having to set breakpoints, but because it forces you to stop causing exceptions. If you're interrupted every time there's a problem, it becomes very inconvenient to cause problems. I loved this feature so much when I found it, that I have never turned it off.

As a side effect, this may make you as judgmental as I am about this issue, because your browser will start pausing while you're trying to open a Google Doc or purchase a fidget spinner. You will definitely uninstall LastPass, too.

#2: Have exceptions emailed to you

I use Google Analytics to track client side exceptions in a custom report, and I have that report emailed to me each day. Obviously not all bugs result in exceptions, and not all exceptions cause UI bugs, but it's been a fantastic and free way to find problems before customers or coworkers report them.

Once google analytics tracking is set up, here's how I report exceptions:

window.onerror = msg => ga('send', 'exception', {
    exDescription: JSON.stringify({
        url: window.location.pathname,
        // other app state...

You can send any string you want as the exDescription. I chose to use a JSON string in case I decide to pipe and parse these logs elsewhere in the future.

To set up the report, go to the Customization > Custom Reports tab in your GA dashboard, then click the following buttons:

  • New Custom Report
  • Add metric
  • Exceptions
  • Add dimension
  • Exception Description
  • Save

To harass yourself regularly with this report, click the "Share" button, enter your email address, set your desired frequency, and send.

#3: Use SublimeLinter (or equivalent)

Did you know that your IDE can probably highlight issues right in your JS code as you're typing? Truly a game changer.

Now, I know what some of you are thinking. "Linting has nothing to do with exceptions, it's just for style." Linting can be just for style, or just for exceptions, or both. At the very least you should be linting for the use of undefined variables. No number of spaces per tab is going to make that code work.

Set this up, and you will never again save a file with a silly typo in a variable or function name. I use SublimeLinter with stylelint.

#4: Break your app

One of my weaknesses as a developer is that too often I test the happy path. I don't try uploading 50 images at once because I don't want to waste space in our S3 bucket. I don't try and keep active socket connections to one service from 37 different tabs because the idea of it makes me grimace. It's easy to brush these off as edge cases, but the truth is that they're not. Users aren't worried about your S3 bucket. And project managers don't close tabs, ever.

Userland, as they call it, is a brutal button-mashing hell. Assume that every possible combination of clicks, keystrokes, refreshes, back buttons, and browser resizes will occur with reckless abandon. Keep track of the "edge cases" that broke your app, and try them out yourself periodically. Develop with Chrome in device emulation mode for a while, maybe with internet throttled. Triple-click the back button just to see what happens. Trying to blame the user for their cruelty is a losing battle. Instead, start padding your estimates to give yourself time to break your new features and fix them again. For UI code, you will be more productive at finding bugs (including but not limited to uncaught exceptions) with this keyboard-pounding method than with unit testing. And yes, relax, I write unit tests too.

#5: Set Log Level to Verbose

Okay, this advice is for leveling-up (pun) your console-clearing game. If you've got your exception count flatlined, it's time to start worrying about warnings. For example, have you started marking scroll events as passive yet? It really makes a difference on some devices.

From the console tab in your Chrome developer tools, there is a drop-down in which you can select a log level. Setting this to verbose will provide you with additional information to help you improve your app. Now tell me, why would you possibly not want that information?

Apologies if this screenshot made you think you accidentally right-clicked something.

Alright, I have to admit that for my current main project I don't leave my console log level on verbose. I have a dependency that causes some warnings in Chrome. But I do have plans to open a PR to address this, after which I hope to go full-on verbose logging at all times.

The reasoning behind all of these practices is the same: we are lazy. In any given situation, we will take the laziest path forward. I don't regret being lazy, because technology in general is one big giant attempt to take our laziness to new extremes. But I do want to be proud of my work, so I erect barriers to my own laziness. I hope to make it as inconvenient as possible for me to produce poor quality work, and I encourage you to do the same. Especially you, LastPass.