This is a "Code review" post. This is designed to be copy pasted into code reviews
I often see JavaScript code that looks like:
const logger = Some logger like console, winston, bunyan, pino, debug, etc...
try {
// do something
} catch (err) {
logger.error(err)
// handle error
}
That’s a pretty big no-no because the only way to know where that error came from is from the error traceback. Tracebacks are hard to read, and you’re assuming that your traceback will even make it to your final logs. You may lose it via truncation or newlines.
To fix it, all you have to do is to add a message:
const logger = Some logger like console, winston, bunyan, pino, debug, etc...
try {
// do something
} catch (err) {
logger.error("abc.def: response isn't JSON", { err })
// handle error
}
It has a string that’s searchable, so you can search your logs for “abc.def” and get all of these errors. I’m pretty lazy and I don’t like to think about names so I just name it after the location and the function.
If you know an error was related to something, I like to add a human readable message too, like “response isn’t JSON”. If you’re having trouble coming up with a message, that’s a code smell that your try
block is covering too much code.
To attach the original error, I add it to the JSON like { err }
. Most loggers look for err
and transform it to get better quality logs. I think Bunyan made that popular in JavaScript and everyone copied it. https://github.com/trentm/node-bunyan#standard-serializers
You can and should stuff some more context in there too:
const logger = Some logger like console, winston, bunyan, pino, debug, etc...
try {
// do something
const resp = await fetch(url)
await resp.json()
} catch (err) {
logger.error("abc.def: response isn't JSON", { err, url })
}
The goal is to have all the information you need to re-create the error locally. If you use Sentry, you’ll be used to this https://docs.sentry.io/enriching-error-data/additional-data/#extra-context. Unlike other languages, JavaScript doesn’t have local variables in errors, so we have to do this manually.