Sometimes I don’t fancy debugging a piece of code in the browser. I mean that as in “use the debugger” - I’d much rather see some log output. This can be more useful than step-by-step debugging because the program flow is not interrupted, which can cause strange behavior in its own right, and because log output makes it easier to see how values go in and out of functions as the program runs through its flow.

Since I prefer writing code in a functional style, I often have the problem that it’s not easy to quickly insert console.log calls. For instance I was just looking at this piece of code:

const validate = buildValidate({
  name: value => (value && value.length >= 5 ? "success" : "error")
});

In order to insert a log output statement manually, I would need to add braces and a return statement first, perhaps ending up with something like this:

const validate = buildValidate({
  name: value => {
    console.log("validateName: ", value);
    return value && value.length >= 5 ? "success" : "error";
  }
});

And of course, when I’m done, I’d have to remove the extra elements again. This is tedious and error-prone. I googled for magical solutions and didn’t find any (please let me know if you’re aware of something I missed!), so I ended up writing my own little helper:

const debug = (id, f, options = {}) => {
  const output = options.output || console.log;
  const processResult = options.processResult || (result => result);
  const processArgs = options.processArgs || (args => args);
  return (...args) => {
    output(`DEBUG(${id}): `, processArgs(args));
    const result = f(...args);
    output(`DEBUG(${id}/result): `, processResult(result));
    return result;
  };
};

With the help of this function, I can now “instrument” my original code by simply wrapping my original lambda in a call to debug:

const validate = buildValidate({
  name: debug("validateName", value =>
    value && value.length >= 5 ? "success" : "error"
  )
});

This change is easier to make: with the exception of adding parens for the call to debug, there is no structural change required (such as adding braces).

I’m sure the solution isn’t perfect for all use cases. I’ve added a few options that would allow processing of data before it’s logged — useful for instance when the result is a Promise. As a quick hack, this seems a nice helper for my perhaps peculiar debugging habits!