Vladimir Klepov as a Coder

Five Tricks for Debug-Logging in JavaScript

Cheer up, today is a quick tip day. No rants, no motivation, no existentialism — just a few simple tricks you can use right now.

We'll be talking about console.log and friends for debugging javascript, mostly in the browser. If you don't use devtools debugger — try it, but I'm not here to judge you (unless you use alert). There is at least one case where console is better: you have a method that gets called frequently, and want to inspect the internal state over multiple runs, then drill down on the interesting ones. Pausing on every hit would be extremely tedious.

Logging in concise arrows

If we want to log something inside a function written in concise arrow syntax (the one without curly braces), you might find yourself adding and removing the body and changing formatting — very boring and error-prone:

promise.then(res => res.data.age);
// what else was there in res?
promise.then(res => { // meh the braces... enter...
console.log(res); // this is the thing... enter...
return res; // oh and the "return"

No need to suffer! Since console.log returns undefined, which is falsey, we can just write:

promise.then(res => console.log(res) || res.data.age);

Beware of post-log object mutation

My most painful session of console-debugging was related to this one. Oh, times. I must admit, this problem does not exist for debugger pauses. Yet, for what it's worth, let's say we have a city object, and something's wrong. Let's log it:

const city = { name: 'Vladivostok', poulation: 606589 };
console.log(city); // { name: null, population: 606589 }

What the hell? Where is the name? You try. You try again. You start suspecting V8 just shipped with multi-threading. You try again. Guess what? In a far away area of your code there's a

city.name = null;

The solution is simple: if you see the data look weird (or just want to double-check), dump a clone / cloneDeep (to triple-check) / stringify:

const city = { name: 'Vladivostok', poulation: 606589 };
// "{ "name": "Vladivostok, "population": 606589 }"

Quickly filter logs by condition

Another trick with boolean short-circuiting is conditional logging. Suppose we have an array of users, and there's a bug displaying users from Australia. But if you log all the users, there is a lot of eye-scanning to find the necessary ones. Booelan short-circuiting to the rescue again, with condition && console.log(data)

Bad code style? Sure. But you'll remove it in a minute anyways.

Make your logs stand out

With a lot of logs running around your console, finding the ones you just added is no easy task.

If you use console.error or warn, your line will be brighter-colored and easier to find. At least until you write 20 console.warns.

Dump stack traces with console.error

The final tip will help you find who called the function, instead of how. console.error conveniently captures the stack trace and shows it in a nice collapsible way. You can quickly look around and find all the call sites — very neat.

That's all for today! Hit the comments if you use know another neat logging trick, or want to blame everyone for not using real loggers, or for not using the debugger. Would love to make a teaser for the next post, but have not chosen yet. Hasta la vista!

Hello, friend! My name is Vladimir, and I love writing about web development. If you got down here, you probably enjoyed this article. My goal is to become an independent content creator, and you'll help me get there by buying me a coffee!
More? All articles ever
Older? Let's Make Software Better Newer? OOP for FP lovers: Simplistic Dependency Injection