This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the dumb-mistakes-and-gotchas category.
Last Updated: 2024-11-21
I had the following function as part of a tax calculator:
// userInput is JSON
function calculateNursingInsurance(userInput) {
const isChildless = Number(userInput["number_children"]) == 0
const age = new Date(Date.now()).getFullYear() - Number(userInput["year_of_birth"])
// lots more code using other data properties
// ...
}
When this function was first put into action, the userInput
parameter
always contained the keys number_children
and year_of_birth
.
But as the codebase grew, I re-used this function elsewhere, and passed it a
userInput
object absent some of the properties the internals expect, i.e.
absent number_children
and year_or_birth
. The code "worked" (in the narrow
sense of giving a numerical answer) so I assumed everything was OK.
But in fact there were grave errors and inaccuracies. For example, if no
year_of_birth
was present, then this key's value would be null
and
Number(null)
in JavaScript gives 0
, and the age
, which is calculated as the current year
minus year of birth, would become 2020
, a ripe old age indeed.
When doing conversions of inputs into numbers, consider what happens if they are
null
. In the JavaScript case, is 0
acceptable - or should there be an error
thrown?
Generally be very careful within a function that blindly accepts input without some type-checking or bounds checking. Just because the input "always" has this data now, doesn't mean it will in future.