Sir Charles Antony Richard Hoare has an excellent presentation on why null
was a bad idea.
There are even programming languages that try to eliminate the very problem of receiving a random null
value out of blue: Elm is such language.
In practice
Usually when I encounter a null
related error the fix were kinda straightforward:
- Check the stack trace
- Read the code in the location
- Either understand it immediately ("Oh, me stupid donkey, I tried the wrong parent property!") or put a debug point in.
- Debug the code.
- Fix and cover the error with test cases.
So, on average, I would say these are maybe 20-minute long adventures.
When you swallow the error on the other hand...
Let's see this code:
try {
const result = await apiCall();
const unboxedResult = await result.json();
sendToSomeoneElse(unboxedResult);
} catch {
// nothing here!
}
Now this is way worse! I have no clue why sendToSomeoneElse
was not called. Unless I'm actively developing this particular block of code I would not have any suspicion that there was an error in the first place!
The legendarily bad angularjs
template
There was 2 key design mistakes in version 1 of angularjs
that caused countless hours of fruitless, laborious debugging sessions.
1. Breaking convention of html
When you read this: <div data-something="This is a string!">something</div>
you know that the data-something
attribute is now having a "This is a string!"
string.
In first version of angular
you could write this:
<div ng-repeat="name in names" ng-include src="'template.html'">
Note the moment where the convention is broken: "'template.html'"
Even though we expect the HTML attribute to be parsed automatically to a string
value, the angular
engine differs here: if it is not enclosed in '
single-quotes, it tries to interpret it as an expression or - simply - as a variable.
2. All templating errors were swallowed
Now this is where the real problem started. In case you forgot the single-quotes (and many, many people forgot it), you would now have an invalid expression. However the decision to swallow or templating errors (for whatever reason) meant...
you have had these innocent looking templates that just did not work as you expected!
I still remember vividly when my colleague from another team decided to escalate the question of "Why does not this angular snippet work???" to the "frontend guild". I only answered it immediately: you missed the single-quotes. The mind of my colleagues were blown, how the hell did I know it so quickly?
The reason was that in my previous workplace, with my previous team I had burnt my fingers with this very thing. We also had no clue what was going on, so:
- I wasted many hours alone.
- I wasted then my team members' time to debug the issue.
- We then escalated to a larger group of devs to figure the issue and wasted their time...
- Until someone, just like me later, knew that this is a typical
angular
error.
So I conclude swallowing errors is a grievous mistake and according to my anecdotic evidence, wastes more time than the well-established NullPointerException
.
Top comments (5)
I love NullPointerException because it helps me find bugs in the code and tells me exactly where those bugs are.
Empty catches, or error handlers are far far far worse. I'd say its irremediably worse.
But I'm from the "Writing Solid Code" crowd where "Fail Early, Fail Hard" is the mantra of the day.. not hide your mistakes crowd.
Thanks for the involved comment! I agree totally on the "Fail Early" part and also, a good
NullPointerException
can indeed even help to see where the expectations failed at reality.Also the nice thing was that errors could be ignored but they'd never be surpassed.
In some of the "modern" ways of error handling you have to handle errors everywhere, and that makes bad programmers just write empty blocks so the bug gets hidden.
I think exceptions are better.
In fairness to angular, swallowing all errors is a a basic design decision of the whole front-end stack, from HTML to CSS to traditional JavaScript.
True! I also had a terrible time figuring out why a CSS variable was not initialized 🫣. In this case I applaud more the design decision in other frameworks that dared to break this old ""solution"".