Once upon a time, I'm sitting at my desk, I'm programming the UI, doing my work, and all of a sudden the console turns red, and this pops up:
Uncaught Error: Bad dependency path or symbol. // Stacktrace of compiled JS-code... // Stacktrace of inner library functions...
Yup, this is an error message.
Yup, this is the whole message.
And yup, this is a good example of a bad message.
A good error message follows two basic principles:
- It relies on the fact that everything is on fire and the error must be fixed immediately.
- It takes care of the developers, rather than accusing them of stupidity.
From these principles, I would derive four rules that a good message:
- Says exactly what's broken—which module, function, etc.
- Where exactly is broken—how to find the error.
- Why it got broken—how to reproduce the error, what doesn't add up.
- How to fix it—what to replace with what to make it work.
— Your app isn't working.
— Yeah, but why?
— Because it's broken ¯\_(ツ)_/¯
I already know that the app doesn't work—because it doesn't work. I need to figure out what's causing it.
In the error above it even seems to say what's broken, here - Bad dependency path or symbol. But what exactly: bad dependency path or bad symbol? If a symbol, which one? If dependency path, which one?
Why not make it like this?
Bad dependency path. Cannot find module "superModule".
In the era before transpiling and building JS code (remember? IE7, FTP, jQuery, ah!...) everything was simple. Stacktrace itself told you which line was the problem. Now the browser stacktrace may not help.
Pointing out an error in compiled (or even minified) code is useless. Tell me about source code: module, function, line, symbol—that's what I need to quickly find the error.
Bad dependency path at line 42, character 88 in "entryPoint.js". Cannot find module "superModule".
Yes, if there is a low-level error, syntactic for example, you should write about it. But undefined is not whatever, as if to say, is not enough. Please show me the place which doesn't work: object field, function name, method name.
If there was a high-level error, explain what exactly went wrong: why a different argument is needed here, why specify an absolute path, etc. Give a link to the documentation, that's helpful. Even if the documentation is sparse. Even if the API is “self-documenting”.
Bad dependency path at line 42, character 88 in "entryPoint.js". Cannot find module "superModule". Expected one of extensions: "js", "jsx", "ts", "tsx", "mjs", but tried to import "".
Let's say it became clear what exactly is broken. If the error message tells you how to fix it, that's awesome.
The most human, but also the most resource-intensive way is to tell you step by step what you need to do to make the bug go away. This is what React does in development mode, for example.
Another good way is to show examples of how a function works, what it will return with what arguments. That's what Lodash does in jsdoc and many Python modules in docstring.
Yes, it's cumbersome. But developers will thank you.
Bad dependency at line 42, character 88 in "entryPoint.js". Cannot find module "superModule". Expected one of extensions: "js", "jsx", "ts", "tsx", "mjs", but tried to import "". Check your import extension and make sure file exists. Note that this lib supports only imports with direct link to a file with its extension.
It's just like in Andrey Sitnik's public talk on project promotion.
Developers do not read logs with errors in a chair under a cozy plaid. Give them what they need, briefly, accurately, with examples.
Even if all the points above are met, but the error message blames the developers for being “dumb”, no one would be grateful for this kind of message.
The developers aren't stupid. They may lack context, knowledge, experience. And it also happens that other third-party code conflicts with yours, or the browser is laggy, or the interpreter, or the network, or the hardware... well, you get it.
It's all just effective communication and a desire to help. Maxim Ilyahov wrote about these things in Rules of Work Communication. And an error message is a type of communication, too! With each caring and helpful error message, there is one less crying developer on Earth.